ruby_vcloud_sdk 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  require_relative "infrastructure"
2
2
  require_relative "powerable"
3
3
  require_relative "vm"
4
+ require_relative "network_config"
4
5
 
5
6
  module VCloudSdk
6
7
  class VApp
@@ -28,10 +29,10 @@ module VCloudSdk
28
29
  wait_for_running_tasks(vapp, "VApp #{vapp_name}")
29
30
 
30
31
  Config.logger.info "Deleting vApp #{vapp_name}."
31
- monitor_task(connection.delete(vapp.remove_link),
32
+ monitor_task(connection.delete(vapp.remove_link.href),
32
33
  @session.time_limit[:delete_vapp]) do |task|
33
34
  Config.logger.info "vApp #{vapp_name} deleted."
34
- return task
35
+ return
35
36
  end
36
37
 
37
38
  fail ApiRequestError,
@@ -66,6 +67,12 @@ module VCloudSdk
66
67
  end
67
68
  end
68
69
 
70
+ def vm_exists?(name)
71
+ entity_xml.vms.any? do |vm|
72
+ vm.name == name
73
+ end
74
+ end
75
+
69
76
  def find_vm_by_name(name)
70
77
  entity_xml.vms.each do |vm|
71
78
  return VCloudSdk::VM.new(@session, vm.href) if vm.name == name
@@ -113,10 +120,11 @@ module VCloudSdk
113
120
  payload,
114
121
  Xml::MEDIA_TYPE[:NETWORK_CONFIG_SECTION])
115
122
  monitor_task(task)
123
+ self
116
124
  end
117
125
 
118
126
  def delete_network_by_name(name)
119
- unless list_networks.any? { |network_name| network_name == name}
127
+ unless list_networks.any? { |network_name| network_name == name }
120
128
  fail ObjectNotFoundError,
121
129
  "Network '#{name}' is not found"
122
130
  end
@@ -134,7 +142,7 @@ module VCloudSdk
134
142
  payload,
135
143
  Xml::MEDIA_TYPE[:NETWORK_CONFIG_SECTION])
136
144
  monitor_task(task)
137
- nil
145
+ self
138
146
  end
139
147
 
140
148
  private
@@ -19,7 +19,7 @@ module VCloudSdk
19
19
  :name, :upload_link, :upload_media_link,
20
20
  :instantiate_vapp_template_link
21
21
 
22
- public :find_network_by_name
22
+ public :find_network_by_name, :network_exists?
23
23
 
24
24
  def initialize(session, link)
25
25
  @session = session
@@ -48,6 +48,12 @@ module VCloudSdk
48
48
  fail ObjectNotFoundError, "Storage profile '#{name}' is not found"
49
49
  end
50
50
 
51
+ def storage_profile_exists?(name)
52
+ storage_profile_records.any? do |storage_profile|
53
+ storage_profile.name == name
54
+ end
55
+ end
56
+
51
57
  def vapps
52
58
  entity_xml.vapps.map do |vapp_link|
53
59
  VCloudSdk::VApp.new(@session, vapp_link)
@@ -70,6 +76,12 @@ module VCloudSdk
70
76
  fail ObjectNotFoundError, "VApp '#{name}' is not found"
71
77
  end
72
78
 
79
+ def vapp_exists?(name)
80
+ entity_xml.vapps.any? do |vapp|
81
+ vapp.name == name
82
+ end
83
+ end
84
+
73
85
  def resources
74
86
  cpu = VCloudSdk::CPU.new(entity_xml.available_cpu_cores)
75
87
  memory = VCloudSdk::Memory.new(entity_xml.available_memory_mb)
@@ -123,8 +135,8 @@ module VCloudSdk
123
135
  end
124
136
 
125
137
  def disk_exists?(name)
126
- disks.any? do |disk|
127
- disk.name == name
138
+ list_disks.any? do |disk_name|
139
+ disk_name == name
128
140
  end
129
141
  end
130
142
 
@@ -165,7 +177,7 @@ module VCloudSdk
165
177
  "#{disks.size} disks with name #{name} were found" if disks.size > 1
166
178
 
167
179
  delete_single_disk(disks.first)
168
- nil
180
+ self
169
181
  end
170
182
 
171
183
  def delete_all_disks_by_name(name)
@@ -182,7 +194,7 @@ module VCloudSdk
182
194
 
183
195
  fail CloudError,
184
196
  "Failed to delete one or more of the disks with name '#{name}'. Check logs for details." unless success
185
- nil
197
+ self
186
198
  end
187
199
 
188
200
  def storage_profile_xml_node(name)
@@ -1,3 +1,3 @@
1
1
  module VCloudSdk
2
- VERSION = '0.5.0'
2
+ VERSION = '0.7.0'
3
3
  end
@@ -2,6 +2,7 @@ require "forwardable"
2
2
  require_relative "infrastructure"
3
3
  require_relative "powerable"
4
4
  require_relative "internal_disk"
5
+ require_relative "nic"
5
6
 
6
7
  module VCloudSdk
7
8
  class VM
@@ -92,6 +93,19 @@ module VCloudSdk
92
93
  .map { |network_connection| network_connection.network }
93
94
  end
94
95
 
96
+ def nics
97
+ primary_index = entity_xml
98
+ .network_connection_section
99
+ .primary_network_connection_index
100
+ entity_xml
101
+ .network_connection_section
102
+ .network_connections
103
+ .map do |network_connection|
104
+ VCloudSdk::NIC.new(network_connection,
105
+ network_connection.network_connection_index == primary_index)
106
+ end
107
+ end
108
+
95
109
  def independent_disks
96
110
  hardware_section = entity_xml.hardware_section
97
111
  disks = []
@@ -122,10 +136,10 @@ module VCloudSdk
122
136
  task = connection.post(entity_xml.attach_disk_link.href,
123
137
  disk_attach_or_detach_params(disk),
124
138
  Xml::MEDIA_TYPE[:DISK_ATTACH_DETACH_PARAMS])
125
- task = monitor_task(task)
139
+ monitor_task(task)
126
140
 
127
141
  Config.logger.info "Disk '#{disk.name}' is attached to VM '#{name}'"
128
- task
142
+ self
129
143
  end
130
144
 
131
145
  def detach_disk(disk)
@@ -143,10 +157,10 @@ module VCloudSdk
143
157
  task = connection.post(entity_xml.detach_disk_link.href,
144
158
  disk_attach_or_detach_params(disk),
145
159
  Xml::MEDIA_TYPE[:DISK_ATTACH_DETACH_PARAMS])
146
- task = monitor_task(task)
160
+ monitor_task(task)
147
161
 
148
162
  Config.logger.info "Disk '#{disk.name}' is detached from VM '#{name}'"
149
- task
163
+ self
150
164
  end
151
165
 
152
166
  def insert_media(catalog_name, media_file_name)
@@ -163,6 +177,7 @@ module VCloudSdk
163
177
  media_insert_or_eject_params(media),
164
178
  Xml::MEDIA_TYPE[:MEDIA_INSERT_EJECT_PARAMS])
165
179
  monitor_task(task)
180
+ self
166
181
  end
167
182
 
168
183
  def eject_media(catalog_name, media_file_name)
@@ -179,6 +194,7 @@ module VCloudSdk
179
194
  media_insert_or_eject_params(media),
180
195
  Xml::MEDIA_TYPE[:MEDIA_INSERT_EJECT_PARAMS])
181
196
  monitor_task(task)
197
+ self
182
198
  end
183
199
 
184
200
  def add_nic(
@@ -203,7 +219,7 @@ module VCloudSdk
203
219
  fail CloudError,
204
220
  "VM #{name} is powered-on and cannot add NIC." if is_status?(payload, :POWERED_ON)
205
221
 
206
- nic_index = list_networks.size # nic index begins with 0
222
+ nic_index = add_nic_index
207
223
 
208
224
  Config.logger
209
225
  .info("Adding NIC #{nic_index}, network #{network_name} using mode '#{ip_addressing_mode}' #{ip.nil? ? "" : "IP: #{ip}"}")
@@ -230,6 +246,20 @@ module VCloudSdk
230
246
  payload,
231
247
  Xml::MEDIA_TYPE[:VM])
232
248
  monitor_task(task)
249
+ self
250
+ end
251
+
252
+ def delete_nics(*nics)
253
+ payload = entity_xml
254
+ fail CloudError,
255
+ "VM #{name} is powered-on and cannot delete NIC." if is_status?(payload, :POWERED_ON)
256
+
257
+ payload.delete_nics(*nics)
258
+ task = connection.post(payload.reconfigure_link.href,
259
+ payload,
260
+ Xml::MEDIA_TYPE[:VM])
261
+ monitor_task(task)
262
+ self
233
263
  end
234
264
 
235
265
  def product_section_properties
@@ -240,8 +270,8 @@ module VCloudSdk
240
270
  end
241
271
 
242
272
  def product_section_properties=(properties)
243
- Config.logger
244
- .info("Updating VM #{name} production sections with properties: #{properties.pretty_inspect}")
273
+ Config.logger.info(
274
+ "Updating VM #{name} production sections with properties: #{properties.inspect}")
245
275
  task = connection.put(entity_xml.product_sections_link.href,
246
276
  product_section_list_params(properties),
247
277
  Xml::MEDIA_TYPE[:PRODUCT_SECTIONS])
@@ -288,10 +318,35 @@ module VCloudSdk
288
318
  payload,
289
319
  Xml::MEDIA_TYPE[:VM])
290
320
  monitor_task(task)
321
+ self
322
+ end
323
+
324
+ def delete_internal_disk_by_name(name)
325
+ payload = entity_xml
326
+
327
+ unless payload.delete_hard_disk?(name)
328
+ fail ObjectNotFoundError, "Internal disk '#{name}' is not found"
329
+ end
330
+
331
+ task = connection.post(payload.reconfigure_link.href,
332
+ payload,
333
+ Xml::MEDIA_TYPE[:VM])
334
+ monitor_task(task)
335
+ self
291
336
  end
292
337
 
293
338
  private
294
339
 
340
+ def add_nic_index
341
+ # nic index begins with 0
342
+ i = 0
343
+ nic_indexes = nics.map { |n| n.nic_index }
344
+ while (nic_indexes.include?(i))
345
+ i += 1
346
+ end
347
+ i
348
+ end
349
+
295
350
  def disk_attach_or_detach_params(disk)
296
351
  Xml::WrapperFactory
297
352
  .create_instance("DiskAttachOrDetachParams")
@@ -42,24 +42,69 @@ module VCloudSdk
42
42
  @local_exists = true
43
43
 
44
44
  locality.each do |k,v|
45
- node_sp = create_child("SourcedVmInstantiationParams")
45
+ node_sp = create_child("SourcedVmInstantiationParams",
46
+ namespace.prefix,
47
+ namespace.href)
46
48
  is_source_delete.node.after(node_sp)
47
49
 
48
- node_sv = add_child("Source", nil, nil, node_sp)
50
+ node_sv = add_child("Source",
51
+ namespace.prefix,
52
+ namespace.href,
53
+ node_sp)
49
54
  node_sv["type"] = k.type
50
55
  node_sv["name"] = k.name
51
56
  node_sv["href"] = k.href
52
57
 
53
- node_lp = create_child("LocalityParams")
58
+ node_lp = create_child("LocalityParams",
59
+ namespace.prefix,
60
+ namespace.href)
54
61
  node_sv.after(node_lp)
55
62
 
56
- node_re = add_child("ResourceEntity", nil, nil, node_lp)
63
+ node_re = add_child("ResourceEntity",
64
+ namespace.prefix,
65
+ namespace.href,
66
+ node_lp)
57
67
  node_re["type"] = v.type
58
68
  node_re["name"] = v.name
59
69
  node_re["href"] = v.href
60
70
  end
61
71
  end
62
72
 
73
+ def set_network_config(vapp_network_name, vdc_netowrk_href, fence_mode)
74
+ instantiation_param = get_nodes("InstantiationParams").first
75
+
76
+ net_config_section = add_child("NetworkConfigSection",
77
+ namespace.prefix,
78
+ namespace.href,
79
+ instantiation_param.node)
80
+
81
+ ovf_info = add_child("Info", "ovf", OVF, net_config_section)
82
+ ovf_info.content = "Configuration parameters for logical networks"
83
+
84
+ network_config = create_child("NetworkConfig",
85
+ namespace.prefix,
86
+ namespace.href)
87
+ ovf_info.after(network_config)
88
+ network_config["networkName"] = vapp_network_name
89
+
90
+ configuration = add_child("Configuration",
91
+ namespace.prefix,
92
+ namespace.href,
93
+ network_config)
94
+
95
+ parent_network = add_child("ParentNetwork",
96
+ namespace.prefix,
97
+ namespace.href,
98
+ configuration)
99
+ parent_network["href"] = vdc_netowrk_href
100
+
101
+ fence_node = create_child("FenceMode",
102
+ namespace.prefix,
103
+ namespace.href)
104
+ parent_network.after(fence_node)
105
+ fence_node.content = fence_mode
106
+ end
107
+
63
108
  private
64
109
 
65
110
  def is_source_delete
@@ -1,6 +1,5 @@
1
1
  module VCloudSdk
2
2
  module Xml
3
-
4
3
  class NetworkConnection < Wrapper
5
4
  def network
6
5
  @root["network"]
@@ -16,15 +15,18 @@ module VCloudSdk
16
15
  end
17
16
 
18
17
  def network_connection_index=(value)
19
- unless get_nodes("NetworkConnectionIndex").first
18
+ index_node = get_nodes("NetworkConnectionIndex").first
19
+ if index_node.nil?
20
20
  index_node = create_child("NetworkConnectionIndex")
21
21
  add_child(index_node)
22
22
  end
23
- get_nodes("NetworkConnectionIndex").first.content = value
23
+ index_node.content = value
24
24
  end
25
25
 
26
26
  def ip_address
27
- get_nodes("IpAddress").first.content
27
+ ip_address_node = get_nodes("IpAddress").first
28
+ return if ip_address_node.nil?
29
+ ip_address_node.content
28
30
  end
29
31
 
30
32
  def ip_address=(value)
@@ -59,13 +61,13 @@ module VCloudSdk
59
61
  end
60
62
 
61
63
  def ip_address_allocation_mode=(value)
62
- if !IP_ADDRESSING_MODE.values.include?(value)
63
- raise ArgumentError, "Invalid IP addressing mode. Valid modes " +
64
- "are: #{IP_ADDRESSING_MODE.values.join(" ")}"
64
+ unless IP_ADDRESSING_MODE.values.include?(value)
65
+ fail ArgumentError,
66
+ "Invalid IP addressing mode. Valid modes " +
67
+ "are: #{IP_ADDRESSING_MODE.values.join(" ")}"
65
68
  end
66
69
  get_nodes("IpAddressAllocationMode").first.content = value
67
70
  end
68
71
  end
69
-
70
72
  end
71
73
  end
@@ -1,6 +1,5 @@
1
1
  module VCloudSdk
2
2
  module Xml
3
-
4
3
  class NetworkConnectionSection < Wrapper
5
4
  def add_item(item)
6
5
  link_node = get_nodes("Link").first
@@ -12,10 +11,11 @@ module VCloudSdk
12
11
  end
13
12
 
14
13
  def network_connection(index)
15
- net = network_connections.find {
16
- |n| n.network_connection_index == index.to_s }
14
+ net = network_connections.find do |n|
15
+ n.network_connection_index == index.to_s
16
+ end
17
17
  unless net
18
- raise ObjectNotFoundError, "Network connection #{index} does not exist."
18
+ fail ObjectNotFoundError, "Network connection #{index} does not exist."
19
19
  end
20
20
  net
21
21
  end
@@ -38,26 +38,27 @@ module VCloudSdk
38
38
  connection = network_connection(index)
39
39
  if connection
40
40
  connection.node.remove
41
- reconcile_primary_network()
41
+ reconcile_primary_network
42
42
  else
43
- raise ObjectNotFoundError,
44
- "Cannot remove network connection #{index}: does not exist."
43
+ fail ObjectNotFoundError,
44
+ "Cannot remove network connection #{index}: does not exist."
45
45
  end
46
46
  end
47
47
 
48
48
  private
49
49
 
50
- def reconcile_primary_network()
50
+ def reconcile_primary_network
51
51
  new_primary = network_connections.first
52
52
  if new_primary
53
- self.primary_network_connection_index =
54
- new_primary.network_connection_index
53
+ primary_index = new_primary.network_connection_index
54
+ self.primary_network_connection_index = primary_index
55
+ primary_index
55
56
  else
56
57
  primary = get_nodes("PrimaryNetworkConnectionIndex").first
57
58
  primary.node.remove if primary
59
+ nil
58
60
  end
59
61
  end
60
62
  end
61
-
62
63
  end
63
64
  end
@@ -1,6 +1,12 @@
1
1
  module VCloudSdk
2
2
  module Xml
3
3
  class Org < Wrapper
4
+ def vdcs
5
+ get_nodes(XML_TYPE[:LINK],
6
+ { type: MEDIA_TYPE[:VDC] },
7
+ true)
8
+ end
9
+
4
10
  def vdc_link(name)
5
11
  get_nodes(XML_TYPE[:LINK],
6
12
  { type: MEDIA_TYPE[:VDC],
@@ -5,31 +5,56 @@ module VCloudSdk
5
5
  property_node = add_child("Property",
6
6
  ovf_namespace_prefix,
7
7
  OVF)
8
- property_node["#{ovf_namespace_prefix}:type"] = property["type"].nil? ? "string" : property["type"]
8
+ property_node["#{ovf_namespace_prefix}:type"] =
9
+ property["type"].nil? ? "string" : property["type"]
9
10
  property_node["#{ovf_namespace_prefix}:key"] = property["key"]
10
11
  property_node["#{ovf_namespace_prefix}:value"] = property["value"]
11
- property_node["#{ovf_namespace_prefix}:password"] = property["password"] if property["password"]
12
+ property_node["#{ovf_namespace_prefix}:password"] =
13
+ property["password"] if property["password"] # default to false
14
+ property_node["#{ovf_namespace_prefix}:userConfigurable"] =
15
+ property["userConfigurable"] if property["userConfigurable"] # default to false
12
16
 
13
- unless property["Label"].nil?
14
- label_node = add_child("Label", ovf_namespace_prefix, OVF, property_node)
15
- label_node.content = property["Label"]
17
+ %w[Label Description].each do |k|
18
+ add_child_node_property(property_node, property, k)
19
+ end
20
+
21
+ if property["value"].nil?
22
+ value_node = add_child("Value", ovf_namespace_prefix, OVF, property_node)
23
+ value_node.attribute("value").value = property["value"]
16
24
  end
17
25
  end
18
26
 
19
27
  def properties
20
28
  get_nodes("Property", nil, true, OVF).map do |property_node|
21
29
  property = {}
22
- property["type"] = property_node.attribute("type").content
23
- property["key"] = property_node.attribute("key").content
24
- property["value"] = property_node.attribute("value").content
25
- property["password"] = property_node.attribute("password").content
30
+ %w[type key value password userConfigurable].each do |k|
31
+ attr = property_node.attribute(k)
32
+ property[k] = attr.nil? ? "" : attr.content
33
+ end
26
34
 
27
- label_node = property_node.get_nodes("Label", nil, true, OVF).first
28
- property["Label"] = label_node.content unless label_node.nil?
35
+ %w[Label Description].each do |k|
36
+ read_child_node_property(property_node, property, k)
37
+ end
29
38
 
39
+ value_node = property_node.get_nodes("Value", nil, true, OVF).first
40
+ property["value"] = value_node.attribute("value").content unless value_node.nil?
30
41
  property
31
42
  end
32
43
  end
44
+
45
+ private
46
+
47
+ def add_child_node_property(property_node, property, key)
48
+ unless property[key].nil?
49
+ child_node = add_child(key, ovf_namespace_prefix, OVF, property_node)
50
+ child_node.content = property[key]
51
+ end
52
+ end
53
+
54
+ def read_child_node_property(property_node, property, key)
55
+ child_node = property_node.get_nodes(key, nil, true, OVF).first
56
+ property[key] = child_node.content unless child_node.nil?
57
+ end
33
58
  end
34
59
  end
35
60
  end
@@ -35,8 +35,9 @@ module VCloudSdk
35
35
  end
36
36
 
37
37
  def nics
38
- items = hardware.find_all {|h| h.get_rasd_content(
39
- RASD_TYPES[:RESOURCE_TYPE]) == HARDWARE_TYPE[:NIC] }
38
+ items = hardware.select do |h|
39
+ h.get_rasd_content(RASD_TYPES[:RESOURCE_TYPE]) == HARDWARE_TYPE[:NIC]
40
+ end
40
41
  items.map { |i| NicItemWrapper.new(i) }
41
42
  end
42
43
 
@@ -45,14 +46,29 @@ module VCloudSdk
45
46
  end
46
47
 
47
48
  def remove_hw(hw_type, index)
48
- item = hardware.find { |h|
49
+ index = index.to_s
50
+ item = hardware.find do |h|
49
51
  h.get_rasd_content(RASD_TYPES[:RESOURCE_TYPE]) == hw_type &&
50
- h.get_rasd_content(RASD_TYPES[:ADDRESS_ON_PARENT]) == index }
52
+ h.get_rasd_content(RASD_TYPES[:ADDRESS_ON_PARENT]) == index
53
+ end
51
54
  if item
52
55
  item.node.remove
53
56
  else
54
- raise ObjectNotFoundError,
55
- "Cannot remove hw item #{hw_type}:#{index}, does not exist."
57
+ fail ObjectNotFoundError,
58
+ "Cannot remove hw item #{hw_type}:#{index}, does not exist."
59
+ end
60
+ end
61
+
62
+ def reconcile_primary_network(primary_index)
63
+ primary_index = primary_index.to_s
64
+ hardware.select do |item|
65
+ item.get_rasd_content(RASD_TYPES[:RESOURCE_TYPE]) == HARDWARE_TYPE[:NIC]
66
+ end.each do |item|
67
+ if item.get_rasd_content(RASD_TYPES[:ADDRESS_ON_PARENT]) == primary_index
68
+ item.get_rasd(RASD_TYPES[:CONNECTION]).attribute("primaryNetworkConnection").value = "true"
69
+ else
70
+ item.get_rasd(RASD_TYPES[:CONNECTION]).attribute("primaryNetworkConnection").value = "false"
71
+ end
56
72
  end
57
73
  end
58
74
 
@@ -117,6 +117,17 @@ module VCloudSdk
117
117
  "busType", VCLOUD_NAMESPACE)] = bus_type
118
118
  end
119
119
 
120
+ def delete_hard_disk?(disk_name)
121
+ hardware_section.hard_disks.each do |disk|
122
+ if disk.element_name == disk_name
123
+ disk.node.remove
124
+ return true
125
+ end
126
+ end
127
+
128
+ false
129
+ end
130
+
120
131
  def change_cpu_count(quantity)
121
132
  @logger.debug("Updating CPU count on vm #{name} to #{quantity} ")
122
133
  item = hardware_section.cpu
@@ -132,7 +143,7 @@ module VCloudSdk
132
143
  # Deletes NIC from VM. Accepts variable number of arguments for NICs.
133
144
  # To delete all NICs from VM use the splat operator
134
145
  # ex: delete_nic(vm, *vm.hardware_section.nics)
135
- def delete_nic(*nics)
146
+ def delete_nics(*nics)
136
147
  # Trying to remove a NIC without removing the network connection
137
148
  # first will cause an error. Removing the network connection of a NIC
138
149
  # in the NetworkConnectionSection will automatically delete the NIC.
@@ -141,8 +152,9 @@ module VCloudSdk
141
152
  nics.each do |nic|
142
153
  nic_index = nic.nic_index
143
154
  @logger.info("Removing NIC #{nic_index} from VM #{name}")
144
- net_conn_section.remove_network_connection(nic_index)
155
+ primary_index = net_conn_section.remove_network_connection(nic_index)
145
156
  vhw_section.remove_nic(nic_index)
157
+ vhw_section.reconcile_primary_network(primary_index) if primary_index
146
158
  end
147
159
  end
148
160