vagrant-google 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +12 -4
- data/.ruby-version +2 -2
- data/CHANGELOG.md +28 -0
- data/Gemfile +2 -4
- data/README.md +42 -26
- data/lib/vagrant-google/action.rb +10 -0
- data/lib/vagrant-google/action/run_instance.rb +128 -79
- data/lib/vagrant-google/action/setup_winrm_password.rb +72 -0
- data/lib/vagrant-google/action/start_instance.rb +4 -4
- data/lib/vagrant-google/config.rb +80 -35
- data/lib/vagrant-google/version.rb +1 -1
- data/locales/en.yml +7 -4
- data/tasks/changelog.rake +40 -0
- data/test/acceptance/skeletons/image_family/Vagrantfile +2 -0
- data/test/unit/common/config_test.rb +107 -42
- data/vagrant-google.gemspec +4 -3
- metadata +27 -13
- data/.rubocop_todo.yml +0 -305
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright 2015 Google Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
#
|
15
|
+
# Changes:
|
16
|
+
# April 2019: Modified example found here:
|
17
|
+
# https://github.com/GoogleCloudPlatform/compute-image-windows/blob/master/examples/windows_auth_python_sample.py
|
18
|
+
# to enable WinRM with vagrant.
|
19
|
+
|
20
|
+
module VagrantPlugins
|
21
|
+
module Google
|
22
|
+
module Action
|
23
|
+
# Sets up a temporary WinRM password using Google's method for
|
24
|
+
# establishing a new password over encrypted channels.
|
25
|
+
class SetupWinrmPassword
|
26
|
+
def initialize(app, env)
|
27
|
+
@app = app
|
28
|
+
@logger = Log4r::Logger.new("vagrant_google::action::setup_winrm_password")
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup_password(env, instance, zone, user)
|
32
|
+
# Setup
|
33
|
+
compute = env[:google_compute]
|
34
|
+
server = compute.servers.get(instance, zone)
|
35
|
+
password = server.reset_windows_password(user)
|
36
|
+
|
37
|
+
env[:ui].info("Temp Password: #{password}")
|
38
|
+
|
39
|
+
password
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(env)
|
43
|
+
# Get the configs
|
44
|
+
zone = env[:machine].provider_config.zone
|
45
|
+
zone_config = env[:machine].provider_config.get_zone_config(zone)
|
46
|
+
|
47
|
+
instance = zone_config.name
|
48
|
+
user = env[:machine].config.winrm.username
|
49
|
+
pass = env[:machine].config.winrm.password
|
50
|
+
|
51
|
+
# Get Temporary Password, set WinRM password
|
52
|
+
temp_pass = setup_password(env, instance, zone, user)
|
53
|
+
env[:machine].config.winrm.password = temp_pass
|
54
|
+
|
55
|
+
# Wait for WinRM To be Ready
|
56
|
+
env[:ui].info("Waiting for WinRM To be ready")
|
57
|
+
env[:machine].communicate.wait_for_ready(60)
|
58
|
+
|
59
|
+
# Use WinRM to Change Password to one in Vagrantfile
|
60
|
+
env[:ui].info("Changing password from temporary to winrm password")
|
61
|
+
winrmcomm = VagrantPlugins::CommunicatorWinRM::Communicator.new(env[:machine])
|
62
|
+
cmd = "net user #{user} #{pass}"
|
63
|
+
opts = { elevated: true }
|
64
|
+
winrmcomm.test(cmd, opts)
|
65
|
+
|
66
|
+
# Update WinRM password to reflect updated one
|
67
|
+
env[:machine].config.winrm.password = pass
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -65,9 +65,9 @@ module VagrantPlugins
|
|
65
65
|
@logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
|
66
66
|
|
67
67
|
unless env[:interrupted]
|
68
|
-
env[:metrics]["
|
69
|
-
# Wait for
|
70
|
-
env[:ui].info(I18n.t("vagrant_google.
|
68
|
+
env[:metrics]["instance_comm_time"] = Util::Timer.time do
|
69
|
+
# Wait for Comms to be ready.
|
70
|
+
env[:ui].info(I18n.t("vagrant_google.waiting_for_comm"))
|
71
71
|
while true
|
72
72
|
# If we're interrupted then just back out
|
73
73
|
break if env[:interrupted]
|
@@ -76,7 +76,7 @@ module VagrantPlugins
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
@logger.info("Time for
|
79
|
+
@logger.info("Time for Comms ready: #{env[:metrics]["instance_comm_time"]}")
|
80
80
|
|
81
81
|
# Ready and booted!
|
82
82
|
env[:ui].info(I18n.t("vagrant_google.ready"))
|
@@ -178,38 +178,68 @@ module VagrantPlugins
|
|
178
178
|
# @return [Array<Hash>]
|
179
179
|
attr_accessor :additional_disks
|
180
180
|
|
181
|
+
# (Optional - Override default WinRM setup before for Public Windows images)
|
182
|
+
#
|
183
|
+
# @return [Boolean]
|
184
|
+
attr_accessor :setup_winrm_password
|
185
|
+
|
186
|
+
# Accelerators
|
187
|
+
#
|
188
|
+
# @return [Array<Hash>]
|
189
|
+
attr_accessor :accelerators
|
190
|
+
|
191
|
+
# whether the instance has Secure Boot enabled
|
192
|
+
#
|
193
|
+
# @return Boolean
|
194
|
+
attr_accessor :enable_secure_boot
|
195
|
+
|
196
|
+
# whether the instance has the vTPM enabled
|
197
|
+
#
|
198
|
+
# @return Boolean
|
199
|
+
attr_accessor :enable_vtpm
|
200
|
+
|
201
|
+
# whether the instance has integrity monitoring enabled
|
202
|
+
#
|
203
|
+
# @return Boolean
|
204
|
+
attr_accessor :enable_integrity_monitoring
|
205
|
+
|
181
206
|
def initialize(zone_specific=false)
|
182
|
-
@google_json_key_location
|
183
|
-
@google_project_id
|
184
|
-
@image
|
185
|
-
@image_family
|
186
|
-
@image_project_id
|
187
|
-
@instance_group
|
188
|
-
@machine_type
|
189
|
-
@disk_size
|
190
|
-
@disk_name
|
191
|
-
@disk_type
|
192
|
-
@metadata
|
193
|
-
@name
|
194
|
-
@network
|
195
|
-
@network_project_id
|
196
|
-
@subnetwork
|
197
|
-
@tags
|
198
|
-
@labels
|
199
|
-
@can_ip_forward
|
200
|
-
@external_ip
|
201
|
-
@network_ip
|
202
|
-
@use_private_ip
|
203
|
-
@autodelete_disk
|
204
|
-
@preemptible
|
205
|
-
@auto_restart
|
206
|
-
@on_host_maintenance
|
207
|
-
@instance_ready_timeout
|
208
|
-
@zone
|
209
|
-
@scopes
|
210
|
-
@service_accounts
|
211
|
-
@service_account
|
212
|
-
@additional_disks
|
207
|
+
@google_json_key_location = UNSET_VALUE
|
208
|
+
@google_project_id = UNSET_VALUE
|
209
|
+
@image = UNSET_VALUE
|
210
|
+
@image_family = UNSET_VALUE
|
211
|
+
@image_project_id = UNSET_VALUE
|
212
|
+
@instance_group = UNSET_VALUE
|
213
|
+
@machine_type = UNSET_VALUE
|
214
|
+
@disk_size = UNSET_VALUE
|
215
|
+
@disk_name = UNSET_VALUE
|
216
|
+
@disk_type = UNSET_VALUE
|
217
|
+
@metadata = {}
|
218
|
+
@name = UNSET_VALUE
|
219
|
+
@network = UNSET_VALUE
|
220
|
+
@network_project_id = UNSET_VALUE
|
221
|
+
@subnetwork = UNSET_VALUE
|
222
|
+
@tags = []
|
223
|
+
@labels = {}
|
224
|
+
@can_ip_forward = UNSET_VALUE
|
225
|
+
@external_ip = UNSET_VALUE
|
226
|
+
@network_ip = UNSET_VALUE
|
227
|
+
@use_private_ip = UNSET_VALUE
|
228
|
+
@autodelete_disk = UNSET_VALUE
|
229
|
+
@preemptible = UNSET_VALUE
|
230
|
+
@auto_restart = UNSET_VALUE
|
231
|
+
@on_host_maintenance = UNSET_VALUE
|
232
|
+
@instance_ready_timeout = UNSET_VALUE
|
233
|
+
@zone = UNSET_VALUE
|
234
|
+
@scopes = UNSET_VALUE
|
235
|
+
@service_accounts = UNSET_VALUE
|
236
|
+
@service_account = UNSET_VALUE
|
237
|
+
@additional_disks = []
|
238
|
+
@setup_winrm_password = UNSET_VALUE
|
239
|
+
@accelerators = []
|
240
|
+
@enable_secure_boot = UNSET_VALUE
|
241
|
+
@enable_vtpm = UNSET_VALUE
|
242
|
+
@enable_integrity_monitoring = UNSET_VALUE
|
213
243
|
|
214
244
|
# Internal state (prefix with __ so they aren't automatically
|
215
245
|
# merged)
|
@@ -275,12 +305,10 @@ module VagrantPlugins
|
|
275
305
|
result.instance_variable_set(:@__zone_config, new_zone_config)
|
276
306
|
|
277
307
|
# Merge in the metadata
|
278
|
-
result.metadata.merge
|
279
|
-
result.metadata.merge!(other.metadata)
|
308
|
+
result.metadata = self.metadata.merge(other.metadata)
|
280
309
|
|
281
310
|
# Merge in the labels
|
282
|
-
result.labels.merge
|
283
|
-
result.labels.merge!(other.labels)
|
311
|
+
result.labels = self.labels.merge(other.labels)
|
284
312
|
|
285
313
|
# Merge in the tags
|
286
314
|
result.tags |= self.tags
|
@@ -382,11 +410,23 @@ module VagrantPlugins
|
|
382
410
|
# Default IAM service account
|
383
411
|
@service_account = nil if @service_account == UNSET_VALUE
|
384
412
|
|
413
|
+
# Default Setup WinRM Password
|
414
|
+
@setup_winrm_password = nil if @setup_winrm_password == UNSET_VALUE
|
415
|
+
|
385
416
|
# Config option service_accounts is deprecated
|
386
417
|
if @service_accounts
|
387
418
|
@scopes = @service_accounts
|
388
419
|
end
|
389
420
|
|
421
|
+
# enable_secure_boot defaults to nil
|
422
|
+
@enable_secure_boot = false if @enable_secure_boot == UNSET_VALUE
|
423
|
+
|
424
|
+
# enable_vtpm defaults to nil
|
425
|
+
@enable_vtpm = false if @enable_vtpm == UNSET_VALUE
|
426
|
+
|
427
|
+
# enable_integrity_monitoring defaults to nil
|
428
|
+
@enable_integrity_monitoring = false if @enable_integrity_monitoring == UNSET_VALUE
|
429
|
+
|
390
430
|
# Compile our zone specific configurations only within
|
391
431
|
# NON-zone-SPECIFIC configurations.
|
392
432
|
unless @__zone_specific
|
@@ -444,6 +484,11 @@ module VagrantPlugins
|
|
444
484
|
|
445
485
|
errors << I18n.t("vagrant_google.config.image_required") if config.image.nil? && config.image_family.nil?
|
446
486
|
errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
|
487
|
+
|
488
|
+
if !config.accelerators.empty?
|
489
|
+
errors << I18n.t("vagrant_google.config.on_host_maintenance_invalid_with_accelerators") unless \
|
490
|
+
config.on_host_maintenance == "TERMINATE"
|
491
|
+
end
|
447
492
|
end
|
448
493
|
|
449
494
|
if @service_accounts
|
data/locales/en.yml
CHANGED
@@ -14,8 +14,8 @@ en:
|
|
14
14
|
Instance is not created. Please run `vagrant up` first.
|
15
15
|
ready: |-
|
16
16
|
Machine is booted and ready for use!
|
17
|
-
|
18
|
-
Machine is ready for
|
17
|
+
ready_comm: |-
|
18
|
+
Machine is ready for Communicator access!
|
19
19
|
rsync_not_found_warning: |-
|
20
20
|
Warning! Folder sync disabled because the rsync binary is missing.
|
21
21
|
Make sure rsync is installed and the binary can be found in the PATH.
|
@@ -31,8 +31,8 @@ en:
|
|
31
31
|
Waiting for GCP operation '%{name}' to finish...
|
32
32
|
waiting_for_ready: |-
|
33
33
|
Waiting for instance to become "ready"...
|
34
|
-
|
35
|
-
Waiting for
|
34
|
+
waiting_for_comm: |-
|
35
|
+
Waiting for Communicator to become available...
|
36
36
|
warn_networks: |-
|
37
37
|
Warning! The Google provider doesn't support any of the Vagrant
|
38
38
|
high-level network configurations (`config.vm.network`). They
|
@@ -71,6 +71,9 @@ en:
|
|
71
71
|
"image" must be unset when setting "image_family"
|
72
72
|
service_accounts_deprecaated: |-
|
73
73
|
"service_accounts is deprecated. Please use scopes instead"
|
74
|
+
on_host_maintenance_invalid_with_accelerators: |-
|
75
|
+
"on_host_maintenance" option must be set to "TERMINATE" for instances
|
76
|
+
with accelerators
|
74
77
|
#-------------------------------------------------------------------------------
|
75
78
|
# Translations for exception classes
|
76
79
|
#-------------------------------------------------------------------------------
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
# Helper method to insert text after a line that matches the regex
|
4
|
+
def insert_after_line(file, insert, regex = /^## Next/)
|
5
|
+
tempfile = File.open("#{file}.tmp", "w")
|
6
|
+
f = File.new(file)
|
7
|
+
f.each do |line|
|
8
|
+
tempfile << line
|
9
|
+
next unless line =~ regex
|
10
|
+
|
11
|
+
tempfile << "\n"
|
12
|
+
tempfile << insert
|
13
|
+
tempfile << "\n"
|
14
|
+
end
|
15
|
+
f.close
|
16
|
+
tempfile.close
|
17
|
+
|
18
|
+
FileUtils.mv("#{file}.tmp", file)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Extracts all changes that have been made after the latest pushed tag
|
22
|
+
def changes_since_last_tag
|
23
|
+
`git --no-pager log $(git describe --tags --abbrev=0)..HEAD --grep="Merge" --pretty=format:"%t - %s%n%b%n"`
|
24
|
+
end
|
25
|
+
|
26
|
+
# Extracts all github users contributed since last tag
|
27
|
+
def users_since_last_tag
|
28
|
+
`git --no-pager log $(git describe --tags --abbrev=0)..HEAD --grep="Merge" --pretty=format:"%s" | cut -d' ' -f 6 | cut -d/ -f1 | sort | uniq`
|
29
|
+
end
|
30
|
+
|
31
|
+
namespace :changelog do
|
32
|
+
task :generate do
|
33
|
+
insert_after_line("CHANGELOG.md", changes_since_last_tag, /^## Next/)
|
34
|
+
printf("Users contributed since last release:\n")
|
35
|
+
contributors = users_since_last_tag.split("\n").map { |name| "@" + name }
|
36
|
+
printf("Huge thanks to all our contributors 🎆\n")
|
37
|
+
printf("Special thanks to: " + contributors.join(" ") + "\n")
|
38
|
+
printf("\nI'll merge this and release the gem once all tests pass.\n")
|
39
|
+
end
|
40
|
+
end
|
@@ -7,6 +7,8 @@ Vagrant.configure("2") do |config|
|
|
7
7
|
|
8
8
|
google.zone_config "australia-southeast1-b" do |zone|
|
9
9
|
zone.name = "vagrant-acceptance-preemptible-#{('a'..'z').to_a.sample(8).join}"
|
10
|
+
# Some images no longer fit into default 10GB disk size
|
11
|
+
zone.disk_size = 30
|
10
12
|
zone.disk_type = "pd-ssd"
|
11
13
|
zone.image_family = "centos-7"
|
12
14
|
end
|
@@ -30,26 +30,30 @@ describe VagrantPlugins::Google::Config do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
its("name")
|
34
|
-
its("image")
|
35
|
-
its("image_family")
|
36
|
-
its("image_project_id")
|
37
|
-
its("instance_group")
|
38
|
-
its("zone")
|
39
|
-
its("network")
|
40
|
-
its("machine_type")
|
41
|
-
its("disk_size")
|
42
|
-
its("disk_name")
|
43
|
-
its("disk_type")
|
44
|
-
its("instance_ready_timeout")
|
45
|
-
its("metadata")
|
46
|
-
its("tags")
|
47
|
-
its("labels")
|
48
|
-
its("scopes")
|
49
|
-
its("additional_disks")
|
50
|
-
its("preemptible")
|
51
|
-
its("auto_restart")
|
52
|
-
its("on_host_maintenance")
|
33
|
+
its("name") { should match "i-[0-9]{10}-[0-9a-f]{4}" }
|
34
|
+
its("image") { should be_nil }
|
35
|
+
its("image_family") { should be_nil }
|
36
|
+
its("image_project_id") { should be_nil }
|
37
|
+
its("instance_group") { should be_nil }
|
38
|
+
its("zone") { should == "us-central1-f" }
|
39
|
+
its("network") { should == "default" }
|
40
|
+
its("machine_type") { should == "n1-standard-1" }
|
41
|
+
its("disk_size") { should == 10 }
|
42
|
+
its("disk_name") { should be_nil }
|
43
|
+
its("disk_type") { should == "pd-standard" }
|
44
|
+
its("instance_ready_timeout") { should == 20 }
|
45
|
+
its("metadata") { should == {} }
|
46
|
+
its("tags") { should == [] }
|
47
|
+
its("labels") { should == {} }
|
48
|
+
its("scopes") { should == nil }
|
49
|
+
its("additional_disks") { should == [] }
|
50
|
+
its("preemptible") { should be_falsey }
|
51
|
+
its("auto_restart") { should }
|
52
|
+
its("on_host_maintenance") { should == "MIGRATE" }
|
53
|
+
its("accelerators") { should == [] }
|
54
|
+
its("enable_secure_boot") { should be_falsey }
|
55
|
+
its("enable_vtpm") { should be_falsey }
|
56
|
+
its("enable_integrity_monitoring") { should be_falsey }
|
53
57
|
end
|
54
58
|
|
55
59
|
describe "overriding defaults" do
|
@@ -57,8 +61,28 @@ describe VagrantPlugins::Google::Config do
|
|
57
61
|
# simple boilerplate test, so I cut corners here. It just sets
|
58
62
|
# each of these attributes to "foo" in isolation, and reads the value
|
59
63
|
# and asserts the proper result comes back out.
|
60
|
-
[
|
61
|
-
|
64
|
+
[
|
65
|
+
:name,
|
66
|
+
:image,
|
67
|
+
:image_family,
|
68
|
+
:image_project_id,
|
69
|
+
:zone,
|
70
|
+
:instance_ready_timeout,
|
71
|
+
:machine_type,
|
72
|
+
:disk_size,
|
73
|
+
:disk_name,
|
74
|
+
:disk_type,
|
75
|
+
:network,
|
76
|
+
:network_project_id,
|
77
|
+
:metadata,
|
78
|
+
:labels,
|
79
|
+
:can_ip_forward,
|
80
|
+
:external_ip,
|
81
|
+
:autodelete_disk,
|
82
|
+
:enable_secure_boot,
|
83
|
+
:enable_vtpm,
|
84
|
+
:enable_integrity_monitoring,
|
85
|
+
].each do |attribute|
|
62
86
|
|
63
87
|
it "should not default #{attribute} if overridden" do
|
64
88
|
instance.send("#{attribute}=".to_sym, "foo")
|
@@ -89,6 +113,14 @@ describe VagrantPlugins::Google::Config do
|
|
89
113
|
errors = instance.validate("foo")["Google Provider"]
|
90
114
|
expect(errors).to include(/on_host_maintenance_invalid_on_preemptible/)
|
91
115
|
end
|
116
|
+
|
117
|
+
it "should raise error with accelerators and on_host_maintenance is not TERMINATE" do
|
118
|
+
instance.accelerators = [{ :type => "nvidia-tesla-k80" }]
|
119
|
+
instance.on_host_maintenance = "MIGRATE"
|
120
|
+
instance.finalize!
|
121
|
+
errors = instance.validate("foo")["Google Provider"]
|
122
|
+
expect(errors).to include(/on_host_maintenance_invalid_with_accelerators/)
|
123
|
+
end
|
92
124
|
end
|
93
125
|
|
94
126
|
describe "getting credentials from environment" do
|
@@ -128,6 +160,7 @@ describe VagrantPlugins::Google::Config do
|
|
128
160
|
let(:config_network) { "foo" }
|
129
161
|
let(:can_ip_forward) { true }
|
130
162
|
let(:external_ip) { "foo" }
|
163
|
+
let(:accelerators) { [{ :type => "foo" }] }
|
131
164
|
|
132
165
|
def set_test_values(instance)
|
133
166
|
instance.name = config_name
|
@@ -140,6 +173,7 @@ describe VagrantPlugins::Google::Config do
|
|
140
173
|
instance.zone = config_zone
|
141
174
|
instance.can_ip_forward = can_ip_forward
|
142
175
|
instance.external_ip = external_ip
|
176
|
+
instance.accelerators = accelerators
|
143
177
|
end
|
144
178
|
|
145
179
|
it "should raise an exception if not finalized" do
|
@@ -169,6 +203,7 @@ describe VagrantPlugins::Google::Config do
|
|
169
203
|
its("zone") { should == config_zone }
|
170
204
|
its("can_ip_forward") { should == can_ip_forward }
|
171
205
|
its("external_ip") { should == external_ip }
|
206
|
+
its("accelerators") { should == accelerators }
|
172
207
|
end
|
173
208
|
|
174
209
|
context "with a specific config set" do
|
@@ -197,6 +232,7 @@ describe VagrantPlugins::Google::Config do
|
|
197
232
|
its("zone") { should == zone_name }
|
198
233
|
its("can_ip_forward") { should == can_ip_forward }
|
199
234
|
its("external_ip") { should == external_ip }
|
235
|
+
its("accelerators") { should == accelerators }
|
200
236
|
end
|
201
237
|
|
202
238
|
describe "inheritance of parent config" do
|
@@ -231,47 +267,76 @@ describe VagrantPlugins::Google::Config do
|
|
231
267
|
end
|
232
268
|
|
233
269
|
describe "merging" do
|
234
|
-
let(:
|
235
|
-
let(:
|
270
|
+
let(:current) { described_class.new }
|
271
|
+
let(:other) { described_class.new }
|
272
|
+
|
273
|
+
subject { current.merge(other) }
|
236
274
|
|
237
275
|
it "should merge the metadata" do
|
238
|
-
|
239
|
-
|
276
|
+
current.metadata["one"] = "foo"
|
277
|
+
other.metadata["two"] = "bar"
|
240
278
|
|
241
|
-
|
242
|
-
expect(third.metadata).to eq({
|
279
|
+
expect(subject.metadata).to eq({
|
243
280
|
"one" => "foo",
|
244
281
|
"two" => "bar"
|
245
282
|
})
|
246
283
|
end
|
247
284
|
|
285
|
+
it "should merge the metadata and overwrite older values" do
|
286
|
+
current.metadata = {
|
287
|
+
"one" => "foo",
|
288
|
+
"name" => "current",
|
289
|
+
}
|
290
|
+
|
291
|
+
other.metadata = {
|
292
|
+
"two" => "bar",
|
293
|
+
"name" => "other",
|
294
|
+
}
|
295
|
+
|
296
|
+
expect(subject.metadata).to eq({
|
297
|
+
"one" => "foo",
|
298
|
+
"two" => "bar",
|
299
|
+
"name" => "other",
|
300
|
+
})
|
301
|
+
end
|
302
|
+
|
248
303
|
it "should merge the labels" do
|
249
|
-
|
250
|
-
|
304
|
+
current.labels["one"] = "one"
|
305
|
+
other.labels["two"] = "two"
|
251
306
|
|
252
|
-
|
253
|
-
expect(third.labels).to eq({
|
307
|
+
expect(subject.labels).to eq({
|
254
308
|
"one" => "one",
|
255
309
|
"two" => "two"
|
256
310
|
})
|
257
311
|
end
|
312
|
+
|
313
|
+
it "should merge the labels and overwrite older values" do
|
314
|
+
current.labels["one"] = "one"
|
315
|
+
current.labels["name"] = "current"
|
316
|
+
other.labels["two"] = "two"
|
317
|
+
other.labels["name"] = "other"
|
318
|
+
|
319
|
+
expect(subject.labels).to eq({
|
320
|
+
"one" => "one",
|
321
|
+
"two" => "two",
|
322
|
+
"name" => "other",
|
323
|
+
})
|
324
|
+
end
|
258
325
|
|
259
326
|
it "should merge the tags" do
|
260
|
-
|
261
|
-
|
327
|
+
current.tags = ["foo", "bar"]
|
328
|
+
other.tags = ["biz"]
|
262
329
|
|
263
|
-
|
264
|
-
expect(
|
265
|
-
expect(
|
266
|
-
expect(third.tags).to include("biz")
|
330
|
+
expect(subject.tags).to include("foo")
|
331
|
+
expect(subject.tags).to include("bar")
|
332
|
+
expect(subject.tags).to include("biz")
|
267
333
|
end
|
268
334
|
|
269
335
|
it "should merge the additional_disks" do
|
270
|
-
|
271
|
-
|
336
|
+
current.additional_disks = [{:one => "one"}]
|
337
|
+
other.additional_disks = [{:two => "two"}]
|
272
338
|
|
273
|
-
|
274
|
-
expect(third.additional_disks).to contain_exactly(
|
339
|
+
expect(subject.additional_disks).to contain_exactly(
|
275
340
|
{:one => "one"}, {:two => "two"}
|
276
341
|
)
|
277
342
|
end
|