opennebula 6.10.3 → 6.99.85.pre
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/lib/cloud/CloudClient.rb +3 -3
- data/lib/models/role.rb +349 -823
- data/lib/models/service.rb +156 -80
- data/lib/models/vmrole.rb +703 -0
- data/lib/models/vrrole.rb +284 -0
- data/lib/models.rb +3 -1
- data/lib/opennebula/acl.rb +1 -1
- data/lib/opennebula/acl_pool.rb +1 -1
- data/lib/opennebula/backupjob.rb +1 -1
- data/lib/opennebula/backupjob_pool.rb +1 -1
- data/lib/opennebula/client.rb +1 -1
- data/lib/opennebula/cluster.rb +45 -2
- data/lib/opennebula/cluster_pool.rb +1 -1
- data/lib/opennebula/datastore.rb +1 -1
- data/lib/opennebula/datastore_pool.rb +1 -1
- data/lib/opennebula/document.rb +1 -1
- data/lib/opennebula/document_json.rb +1 -1
- data/lib/opennebula/document_pool.rb +1 -1
- data/lib/opennebula/document_pool_json.rb +1 -1
- data/lib/opennebula/error.rb +1 -1
- data/lib/opennebula/flow/grammar.rb +1 -1
- data/lib/opennebula/flow/service_pool.rb +1 -1
- data/lib/opennebula/flow/service_template.rb +353 -97
- data/lib/opennebula/flow/service_template_ext.rb +3 -3
- data/lib/opennebula/flow/service_template_pool.rb +1 -1
- data/lib/opennebula/flow/validator.rb +458 -410
- data/lib/opennebula/flow.rb +1 -1
- data/lib/opennebula/group.rb +1 -1
- data/lib/opennebula/group_pool.rb +1 -1
- data/lib/opennebula/hook.rb +1 -1
- data/lib/opennebula/hook_log.rb +1 -1
- data/lib/opennebula/hook_pool.rb +1 -1
- data/lib/opennebula/host.rb +1 -60
- data/lib/opennebula/host_pool.rb +1 -1
- data/lib/opennebula/image.rb +1 -1
- data/lib/opennebula/image_pool.rb +1 -1
- data/lib/opennebula/ldap_auth.rb +1 -1
- data/lib/opennebula/ldap_auth_spec.rb +1 -1
- data/lib/opennebula/lockable_ext.rb +1 -1
- data/lib/opennebula/marketplace.rb +1 -1
- data/lib/opennebula/marketplace_pool.rb +1 -1
- data/lib/opennebula/marketplaceapp.rb +1 -1
- data/lib/opennebula/marketplaceapp_ext.rb +14 -211
- data/lib/opennebula/marketplaceapp_pool.rb +1 -1
- data/lib/opennebula/oneflow_client.rb +11 -9
- data/lib/opennebula/pool.rb +1 -1
- data/lib/opennebula/pool_element.rb +1 -1
- data/lib/opennebula/security_group.rb +1 -1
- data/lib/opennebula/security_group_pool.rb +1 -1
- data/lib/opennebula/server_cipher_auth.rb +1 -1
- data/lib/opennebula/server_x509_auth.rb +1 -1
- data/lib/opennebula/ssh_auth.rb +1 -1
- data/lib/opennebula/system.rb +1 -1
- data/lib/opennebula/template.rb +1 -1
- data/lib/opennebula/template_ext.rb +1 -1
- data/lib/opennebula/template_pool.rb +1 -1
- data/lib/opennebula/user.rb +1 -1
- data/lib/opennebula/user_pool.rb +1 -1
- data/lib/opennebula/utils.rb +2 -2
- data/lib/opennebula/vdc.rb +1 -1
- data/lib/opennebula/vdc_pool.rb +1 -1
- data/lib/opennebula/virtual_machine.rb +3 -12
- data/lib/opennebula/virtual_machine_ext.rb +2 -31
- data/lib/opennebula/virtual_machine_pool.rb +1 -1
- data/lib/opennebula/virtual_network.rb +1 -1
- data/lib/opennebula/virtual_network_pool.rb +1 -1
- data/lib/opennebula/virtual_router.rb +1 -1
- data/lib/opennebula/virtual_router_pool.rb +1 -1
- data/lib/opennebula/vm_group.rb +1 -1
- data/lib/opennebula/vm_group_pool.rb +1 -1
- data/lib/opennebula/vntemplate.rb +1 -1
- data/lib/opennebula/vntemplate_pool.rb +1 -1
- data/lib/opennebula/wait_ext.rb +1 -1
- data/lib/opennebula/x509_auth.rb +1 -1
- data/lib/opennebula/xml_element.rb +2 -2
- data/lib/opennebula/xml_pool.rb +1 -1
- data/lib/opennebula/xml_utils.rb +1 -1
- data/lib/opennebula/zone.rb +1 -1
- data/lib/opennebula/zone_pool.rb +1 -1
- data/lib/opennebula.rb +2 -2
- metadata +6 -67
- data/lib/ActionManager.rb +0 -280
- data/lib/CommandManager.rb +0 -328
- data/lib/DriverExecHelper.rb +0 -213
- data/lib/HostSyncManager.rb +0 -111
- data/lib/OpenNebulaDriver.rb +0 -223
- data/lib/VirtualMachineDriver.rb +0 -404
- data/lib/datacenter.rb +0 -1319
- data/lib/datastore.rb +0 -1049
- data/lib/distributed_firewall.rb +0 -293
- data/lib/file_helper.rb +0 -374
- data/lib/host.rb +0 -1518
- data/lib/logical_port.rb +0 -50
- data/lib/logical_switch.rb +0 -77
- data/lib/memoize.rb +0 -74
- data/lib/network.rb +0 -705
- data/lib/nsx_client.rb +0 -157
- data/lib/nsx_component.rb +0 -28
- data/lib/nsx_constants.rb +0 -162
- data/lib/nsx_driver.rb +0 -91
- data/lib/nsx_error.rb +0 -77
- data/lib/nsx_rule.rb +0 -206
- data/lib/nsxt_client.rb +0 -189
- data/lib/nsxt_dfw.rb +0 -196
- data/lib/nsxt_logical_port.rb +0 -94
- data/lib/nsxt_rule.rb +0 -188
- data/lib/nsxt_tz.rb +0 -38
- data/lib/nsxv_client.rb +0 -189
- data/lib/nsxv_dfw.rb +0 -202
- data/lib/nsxv_logical_port.rb +0 -107
- data/lib/nsxv_rule.rb +0 -172
- data/lib/nsxv_tz.rb +0 -41
- data/lib/opaque_network.rb +0 -134
- data/lib/rest_client.rb +0 -191
- data/lib/scripts_common.rb +0 -176
- data/lib/transport_zone.rb +0 -43
- data/lib/vcenter_driver.rb +0 -152
- data/lib/vcenter_importer.rb +0 -626
- data/lib/vi_client.rb +0 -273
- data/lib/vi_helper.rb +0 -328
- data/lib/virtual_machine.rb +0 -3574
- data/lib/virtual_wire.rb +0 -158
- data/lib/vm_device.rb +0 -80
- data/lib/vm_disk.rb +0 -202
- data/lib/vm_folder.rb +0 -69
- data/lib/vm_helper.rb +0 -30
- data/lib/vm_monitor.rb +0 -305
- data/lib/vm_nic.rb +0 -70
- data/lib/vm_template.rb +0 -2112
- data/lib/vmm_importer.rb +0 -165
data/lib/models/service.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
2
|
-
# Copyright 2002-
|
2
|
+
# Copyright 2002-2025, OpenNebula Project, OpenNebula Systems #
|
3
3
|
# #
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
@@ -104,8 +104,8 @@ module OpenNebula
|
|
104
104
|
|
105
105
|
# List of attributes that can't be changed in update operation
|
106
106
|
#
|
107
|
-
#
|
108
|
-
#
|
107
|
+
# user_inputs: it only has sense when deploying, not in running
|
108
|
+
# user_inputs_values: it only has sense when deploying, not in running
|
109
109
|
# deployment: changing this, changes the undeploy operation
|
110
110
|
# log: this is just internal information, no sense to change it
|
111
111
|
# name: this has to be changed using rename operation
|
@@ -115,8 +115,8 @@ module OpenNebula
|
|
115
115
|
# state: this is internal information managed by OneFlow server
|
116
116
|
# start_time: this is internal information managed by OneFlow server
|
117
117
|
IMMUTABLE_ATTRS = [
|
118
|
-
'
|
119
|
-
'
|
118
|
+
'user_inputs',
|
119
|
+
'user_inputs_values',
|
120
120
|
'deployment',
|
121
121
|
'log',
|
122
122
|
'name',
|
@@ -129,6 +129,12 @@ module OpenNebula
|
|
129
129
|
|
130
130
|
LOG_COMP = 'SER'
|
131
131
|
|
132
|
+
# Returns the service name
|
133
|
+
# @return [String] the service name
|
134
|
+
def name
|
135
|
+
@body['name']
|
136
|
+
end
|
137
|
+
|
132
138
|
# Returns the service state
|
133
139
|
# @return [Integer] the service state
|
134
140
|
def state
|
@@ -214,6 +220,10 @@ module OpenNebula
|
|
214
220
|
self['UNAME']
|
215
221
|
end
|
216
222
|
|
223
|
+
def uid
|
224
|
+
self['UID'].to_i
|
225
|
+
end
|
226
|
+
|
217
227
|
def gid
|
218
228
|
self['GID'].to_i
|
219
229
|
end
|
@@ -224,8 +234,9 @@ module OpenNebula
|
|
224
234
|
@body['on_hold']
|
225
235
|
end
|
226
236
|
|
227
|
-
|
228
|
-
|
237
|
+
# Change the `on_hold` option value
|
238
|
+
def on_hold=(on_hold)
|
239
|
+
@body['on_hold'] = on_hold
|
229
240
|
end
|
230
241
|
|
231
242
|
# Replaces this object's client with a new one
|
@@ -237,20 +248,14 @@ module OpenNebula
|
|
237
248
|
# Sets a new state
|
238
249
|
# @param [Integer] the new state
|
239
250
|
# @return [true, false] true if the value was changed
|
240
|
-
|
241
|
-
|
242
|
-
# rubocop:enable Naming/AccessorMethodName
|
243
|
-
if state < 0 || state > STATE_STR.size
|
244
|
-
return false
|
245
|
-
end
|
251
|
+
def state=(state)
|
252
|
+
return if state < 0 || state > STATE_STR.size
|
246
253
|
|
247
254
|
@body['state'] = state.to_i
|
248
255
|
|
249
256
|
msg = "New state: #{STATE_STR[state]}"
|
250
257
|
Log.info LOG_COMP, msg, id
|
251
258
|
log_info(msg)
|
252
|
-
|
253
|
-
true
|
254
259
|
end
|
255
260
|
|
256
261
|
# Returns true if all the nodes are correctly deployed
|
@@ -323,9 +328,6 @@ module OpenNebula
|
|
323
328
|
|
324
329
|
template['start_time'] = Integer(Time.now)
|
325
330
|
|
326
|
-
# Replace $attibute by the corresponding value
|
327
|
-
resolve_attributes(template)
|
328
|
-
|
329
331
|
super(template.to_json, template['name'])
|
330
332
|
end
|
331
333
|
|
@@ -336,38 +338,38 @@ module OpenNebula
|
|
336
338
|
if [Service::STATE['FAILED_DEPLOYING']].include?(state)
|
337
339
|
@roles.each do |_name, role|
|
338
340
|
if role.state == Role::STATE['FAILED_DEPLOYING']
|
339
|
-
role.
|
341
|
+
role.state = Role::STATE['PENDING']
|
340
342
|
end
|
341
343
|
end
|
342
344
|
|
343
|
-
|
345
|
+
self.state = Service::STATE['DEPLOYING']
|
344
346
|
|
345
347
|
elsif state == Service::STATE['FAILED_SCALING']
|
346
348
|
@roles.each do |_name, role|
|
347
349
|
if role.state == Role::STATE['FAILED_SCALING']
|
348
|
-
role.
|
350
|
+
role.state = Role::STATE['SCALING']
|
349
351
|
end
|
350
352
|
end
|
351
353
|
|
352
|
-
|
354
|
+
self.state = Service::STATE['SCALING']
|
353
355
|
|
354
356
|
elsif state == Service::STATE['FAILED_UNDEPLOYING']
|
355
357
|
@roles.each do |_name, role|
|
356
358
|
if role.state == Role::STATE['FAILED_UNDEPLOYING']
|
357
|
-
role.
|
359
|
+
role.state = Role::STATE['RUNNING']
|
358
360
|
end
|
359
361
|
end
|
360
362
|
|
361
|
-
|
363
|
+
self.state = Service::STATE['UNDEPLOYING']
|
362
364
|
|
363
365
|
elsif state == Service::STATE['COOLDOWN']
|
364
366
|
@roles.each do |_name, role|
|
365
367
|
if role.state == Role::STATE['COOLDOWN']
|
366
|
-
role.
|
368
|
+
role.state = Role::STATE['RUNNING']
|
367
369
|
end
|
368
370
|
end
|
369
371
|
|
370
|
-
|
372
|
+
self.state = Service::STATE['RUNNING']
|
371
373
|
|
372
374
|
elsif state == Service::STATE['WARNING']
|
373
375
|
@roles.each do |_name, role|
|
@@ -396,7 +398,7 @@ module OpenNebula
|
|
396
398
|
if @body['roles']
|
397
399
|
@body['roles'].each do |elem|
|
398
400
|
elem['state'] ||= Role::STATE['PENDING']
|
399
|
-
role = Role.
|
401
|
+
role = Role.for(elem, self)
|
400
402
|
@roles[role.name] = role
|
401
403
|
end
|
402
404
|
end
|
@@ -411,7 +413,7 @@ module OpenNebula
|
|
411
413
|
# @return [OpenNebula::Role] New role
|
412
414
|
def add_role(template)
|
413
415
|
template['state'] ||= Role::STATE['PENDING']
|
414
|
-
role = Role.
|
416
|
+
role = Role.for(template, self)
|
415
417
|
|
416
418
|
if @roles[role.name]
|
417
419
|
return OpenNebula::Error.new("Role #{role.name} already exists")
|
@@ -444,7 +446,7 @@ module OpenNebula
|
|
444
446
|
if @body['roles']
|
445
447
|
@body['roles'].each do |elem|
|
446
448
|
elem['state'] ||= Role::STATE['PENDING']
|
447
|
-
role = Role.
|
449
|
+
role = Role.for(elem, self)
|
448
450
|
@roles[role.name] = role
|
449
451
|
end
|
450
452
|
end
|
@@ -540,11 +542,11 @@ module OpenNebula
|
|
540
542
|
# TODO: The update may not change the cardinality, only
|
541
543
|
# the max and min vms...
|
542
544
|
|
543
|
-
role.
|
545
|
+
role.state = Role::STATE['SCALING']
|
544
546
|
|
545
547
|
role.set_default_cooldown_duration
|
546
548
|
|
547
|
-
|
549
|
+
self.state = Service::STATE['SCALING']
|
548
550
|
|
549
551
|
update
|
550
552
|
end
|
@@ -634,6 +636,19 @@ module OpenNebula
|
|
634
636
|
[true, nil]
|
635
637
|
end
|
636
638
|
|
639
|
+
# Fills the service template with the provided values.
|
640
|
+
#
|
641
|
+
# This method replaces placeholders in the service template with corresponding values
|
642
|
+
# Placeholders are expected to be in the format $key.
|
643
|
+
#
|
644
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error otherwise
|
645
|
+
def fill_template
|
646
|
+
generate_template_contents
|
647
|
+
rescue StandardError => e
|
648
|
+
Log.error LOG_COMP, "Error generating VM template contents: #{e.message}"
|
649
|
+
return OpenNebula::Error.new('Error generating VM template contents')
|
650
|
+
end
|
651
|
+
|
637
652
|
def deploy_networks(deploy = true)
|
638
653
|
body = if deploy
|
639
654
|
JSON.parse(self['TEMPLATE/BODY'])
|
@@ -659,9 +674,6 @@ module OpenNebula
|
|
659
674
|
end
|
660
675
|
end if deploy
|
661
676
|
|
662
|
-
# Replace $attibute by the corresponding value
|
663
|
-
resolve_networks(body)
|
664
|
-
|
665
677
|
# @body = template.to_hash
|
666
678
|
|
667
679
|
update_body(body)
|
@@ -726,7 +738,7 @@ module OpenNebula
|
|
726
738
|
if @body['roles']
|
727
739
|
@body['roles'].each do |elem|
|
728
740
|
elem['state'] ||= Role::STATE['PENDING']
|
729
|
-
role = Role.
|
741
|
+
role = Role.for(elem, self)
|
730
742
|
@roles[role.name] = role
|
731
743
|
end
|
732
744
|
end
|
@@ -779,60 +791,124 @@ module OpenNebula
|
|
779
791
|
"#{net}-#{id}"
|
780
792
|
end
|
781
793
|
|
782
|
-
#
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
794
|
+
# Generates and updates the `template_contents` for each role within a service.
|
795
|
+
# This method handles VM attributes (like MEMORY, CPU, etc.) and CONTEXT attributes
|
796
|
+
# within `template_contents` for each role. The contents are generated by combining
|
797
|
+
# the `user_inputs_values` from both the service and the individual role, with the
|
798
|
+
# role inputs taking precedence over the service inputs.
|
799
|
+
#
|
800
|
+
# The method also resolves network configurations for each role by mapping network
|
801
|
+
# IDs from the service-level `networks_values` to the NICs defined in the role's
|
802
|
+
# `template_contents`.
|
803
|
+
#
|
804
|
+
# @example
|
805
|
+
# Given the following input data:
|
806
|
+
# template_contents = {
|
807
|
+
# 'MEMORY' => '1024',
|
808
|
+
# 'NIC' => [
|
809
|
+
# {
|
810
|
+
# 'NAME' => 'NIC_0',
|
811
|
+
# 'NETWORK_ID' => '$private'
|
812
|
+
# }
|
813
|
+
# ]
|
814
|
+
# }
|
815
|
+
#
|
816
|
+
# networks_values = [{"private": {"id":"0"}}]
|
817
|
+
# user_inputs_values = {"ATT_A": "VALUE_A"}
|
818
|
+
#
|
819
|
+
# After executing `generate_template_contents`, the result would be:
|
820
|
+
# {
|
821
|
+
# 'ATT_A' => 'VALUE_A',
|
822
|
+
# 'MEMORY' => '1024',
|
823
|
+
# 'NIC' => [
|
824
|
+
# {
|
825
|
+
# 'NAME' => 'NIC_0',
|
826
|
+
# 'NETWORK_ID' => '0'
|
827
|
+
# }
|
828
|
+
# ],
|
829
|
+
# 'CONTEXT' => {
|
830
|
+
# 'ATT_A' => '$VALUE_A',
|
831
|
+
# }
|
832
|
+
# }
|
833
|
+
#
|
834
|
+
def generate_template_contents
|
835
|
+
service_inputs = @body['user_inputs_values'] || {}
|
836
|
+
service_networks = @body['networks_values'] || []
|
837
|
+
|
838
|
+
@body['roles'].each do |role|
|
839
|
+
template_contents = role['template_contents'] || {}
|
840
|
+
role_inputs = role['user_inputs_values'] || {}
|
841
|
+
role_nets = template_contents['NIC'] || []
|
842
|
+
|
843
|
+
# Resolve networks
|
844
|
+
unless role_nets.empty?
|
845
|
+
template_contents['NIC'] = resolve_networks(role_nets, service_networks)
|
846
|
+
end
|
791
847
|
|
792
|
-
|
848
|
+
# Resolve inputs
|
849
|
+
unless service_inputs.empty? && role_inputs.empty?
|
850
|
+
# role inputs have precedence over service inputs
|
851
|
+
role_inputs = service_inputs.deep_merge(role_inputs)
|
793
852
|
|
794
|
-
role
|
795
|
-
|
796
|
-
|
797
|
-
end
|
853
|
+
# Add the role inputs to the template_contents,
|
854
|
+
# creating the CONTEXT section in case it doesn't exist
|
855
|
+
template_contents['CONTEXT'] = {} unless template_contents.key?('CONTEXT')
|
798
856
|
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
# $CUSTOM1_VAR Any word character
|
803
|
-
# (letter, number, underscore)
|
804
|
-
role['vm_template_contents'].scan(/\$(\w+)/).each do |key|
|
805
|
-
# Check if $ var value is in custom_attrs_values within the role
|
806
|
-
if !role['custom_attrs_values'].nil? && \
|
807
|
-
role['custom_attrs_values'].key?(key[0])
|
808
|
-
role['vm_template_contents'].gsub!(
|
809
|
-
'$'+key[0],
|
810
|
-
role['custom_attrs_values'][key[0]]
|
811
|
-
)
|
812
|
-
next
|
813
|
-
end
|
814
|
-
|
815
|
-
# Check if $ var value is in custom_attrs_values
|
816
|
-
|
817
|
-
next unless !template['custom_attrs_values'].nil? && \
|
818
|
-
template['custom_attrs_values'].key?(key[0])
|
819
|
-
|
820
|
-
role['vm_template_contents'].gsub!(
|
821
|
-
'$'+key[0],
|
822
|
-
template['custom_attrs_values'][key[0]]
|
823
|
-
)
|
857
|
+
role_inputs.each do |key, value|
|
858
|
+
template_contents[key] = value
|
859
|
+
template_contents['CONTEXT'][key] = "$#{key}"
|
824
860
|
end
|
825
861
|
end
|
826
862
|
|
827
|
-
|
863
|
+
role['template_contents'] = template_contents
|
864
|
+
end
|
865
|
+
end
|
828
866
|
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
867
|
+
# Replaces the `NETWORK_ID` placeholders in the given NICs with their corresponding
|
868
|
+
# network IDs based on the provided `networks_values`. This method is used to resolve
|
869
|
+
# dynamic network references (e.g., `$private`) in the role's NIC configuration with
|
870
|
+
# the actual network IDs.
|
871
|
+
#
|
872
|
+
# @param nics [Array<Hash>] An array of NIC hashes for a role. Each NIC hash should
|
873
|
+
# contain a `NETWORK_ID` key, which may have a value that
|
874
|
+
# is a placeholder in the form `$network_name`.
|
875
|
+
# @param networks_values [Array<Hash>] An array of network values, where each value
|
876
|
+
# is a hash containing a network name as the key
|
877
|
+
# and a network configuration as the value. The network
|
878
|
+
# configuration should include an `id` key with the
|
879
|
+
# actual network ID.
|
880
|
+
#
|
881
|
+
# @return [Array<Hash>] An array of NIC hashes with the `NETWORK_ID` placeholders replaced
|
882
|
+
# by the corresponding network IDs from `networks_values`.
|
883
|
+
#
|
884
|
+
# @example
|
885
|
+
# Given the following input data:
|
886
|
+
# nics = [
|
887
|
+
# { 'NAME' => 'NIC_0', 'NETWORK_ID' => '$private' },
|
888
|
+
# { 'NAME' => 'NIC_1', 'NETWORK_ID' => '1' }
|
889
|
+
# ]
|
890
|
+
#
|
891
|
+
# networks_values = [{ 'private' => { 'id' => '0' } }]
|
892
|
+
#
|
893
|
+
# After calling `resolve_networks(nics, networks_values)`, the result would be:
|
894
|
+
# [
|
895
|
+
# { 'NAME' => 'NIC_0', 'NETWORK_ID' => '0' },
|
896
|
+
# { 'NAME' => 'NIC_1', 'NETWORK_ID' => '1' }
|
897
|
+
# ]
|
898
|
+
def resolve_networks(nics, networks_values)
|
899
|
+
nics.each do |nic|
|
900
|
+
next unless nic['NETWORK_ID'].is_a?(String)
|
901
|
+
|
902
|
+
match = nic['NETWORK_ID'].match(/\$(\w+)/)
|
903
|
+
next unless match
|
904
|
+
|
905
|
+
net_name = match[1]
|
906
|
+
network = networks_values.find {|att| att.key?(net_name) }
|
907
|
+
nic['NETWORK_ID'] = network[net_name]['id'] if network
|
833
908
|
end
|
909
|
+
|
910
|
+
nics
|
834
911
|
end
|
835
|
-
# rubocop:enable Layout/LineLength
|
836
912
|
|
837
913
|
end
|
838
914
|
|