Class: Ovirt::Base

Inherits:
Object
  • Object
show all
Extended by:
Logging
Includes:
Logging
Defined in:
lib/ovirt/base.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service, options = {}) ⇒ Base

Returns a new instance of Base.



241
242
243
244
245
246
# File 'lib/ovirt/base.rb', line 241

def initialize(service, options = {})
  @service       = service
  @relationships = options.delete(:relationships) || {}
  @operations    = options.delete(:actions) || {}
  @attributes    = options
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
# File 'lib/ovirt/base.rb', line 258

def method_missing(m, *args)
  if @relationships.key?(m)
    relationship(m)
  elsif @operations.key?(m)
    operation(m, args)
  elsif @attributes.key?(m)
    @attributes[m]
  else
    super
  end
end

Class Attribute Details

.top_level_booleansObject



115
116
117
# File 'lib/ovirt/base.rb', line 115

def self.top_level_booleans
  @top_level_booleans ||= []
end

.top_level_integersObject



107
108
109
# File 'lib/ovirt/base.rb', line 107

def self.top_level_integers
  @top_level_integers ||= []
end

.top_level_objectsObject



91
92
93
# File 'lib/ovirt/base.rb', line 91

def self.top_level_objects
  @top_level_objects ||= []
end

.top_level_stringsObject



99
100
101
# File 'lib/ovirt/base.rb', line 99

def self.top_level_strings
  @top_level_strings ||= []
end

.top_level_timestampsObject



123
124
125
# File 'lib/ovirt/base.rb', line 123

def self.top_level_timestamps
  @top_level_timestamps ||= []
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



239
240
241
# File 'lib/ovirt/base.rb', line 239

def attributes
  @attributes
end

#operationsObject

Returns the value of attribute operations.



239
240
241
# File 'lib/ovirt/base.rb', line 239

def operations
  @operations
end

#relationshipsObject

Returns the value of attribute relationships.



239
240
241
# File 'lib/ovirt/base.rb', line 239

def relationships
  @relationships
end

#serviceObject

Returns the value of attribute service.



239
240
241
# File 'lib/ovirt/base.rb', line 239

def service
  @service
end

Class Method Details

.all(service) ⇒ Object



214
215
216
# File 'lib/ovirt/base.rb', line 214

def self.all(service)
  all_xml_objects(service).collect { |xml| create_from_xml(service, xml) }
end

.all_xml_objects(service) ⇒ Object



208
209
210
211
212
# File 'lib/ovirt/base.rb', line 208

def self.all_xml_objects(service)
  response = service.resource_get(api_endpoint)
  doc      = Nokogiri::XML(response)
  doc.xpath("//#{element_names}/#{element_name}")
end

.api_endpointObject



196
197
198
# File 'lib/ovirt/base.rb', line 196

def self.api_endpoint
  namespace.last.pluralize.downcase
end

.create_from_xml(service, xml) ⇒ Object



6
7
8
# File 'lib/ovirt/base.rb', line 6

def self.create_from_xml(service, xml)
  new(service, parse_xml(xml))
end

.element_nameObject



204
205
206
# File 'lib/ovirt/base.rb', line 204

def self.element_name
  api_endpoint.singularize
end

.element_namesObject



200
201
202
# File 'lib/ovirt/base.rb', line 200

def self.element_names
  element_name.pluralize
end

.find_by_href(service, href) ⇒ Object



230
231
232
233
234
235
236
237
# File 'lib/ovirt/base.rb', line 230

def self.find_by_href(service, href)
  response = service.resource_get(href)
  doc      = Nokogiri::XML(response)
  xml      = doc.xpath("//#{element_name}").first
  create_from_xml(service, xml)
rescue RestClient::ResourceNotFound
  return nil
end

.find_by_id(service, id) ⇒ Object



226
227
228
# File 'lib/ovirt/base.rb', line 226

def self.find_by_id(service, id)
  find_by_href(service, "#{api_endpoint}/#{id}")
end

.find_by_name(service, name) ⇒ Object



218
219
220
221
222
223
224
# File 'lib/ovirt/base.rb', line 218

def self.find_by_name(service, name)
  all_xml_objects(service).each do |xml|
    obj = create_from_xml(service, xml)
    return obj if obj[:name] == name
  end
  nil
end

.has_first_node?(node, path) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/ovirt/base.rb', line 83

def self.has_first_node?(node, path)
  node.xpath(path.to_s).first.present?
end

.hash_from_id_and_href(node) ⇒ Object



30
31
32
33
34
# File 'lib/ovirt/base.rb', line 30

def self.hash_from_id_and_href(node)
  hash = {}
  [:id, :href].each { |key| hash[key] = node[key.to_s] unless node.nil? || node[key.to_s].nil? }
  hash
end


173
174
175
176
177
# File 'lib/ovirt/base.rb', line 173

def self.href_from_creation_status_link(link)
  # "/api/vms/5024ab49-19b5-4176-9568-c004d1c9f256/creation_status/d0e45003-d490-4551-9911-05b3bec682dc"
  # => "/api/vms/5024ab49-19b5-4176-9568-c004d1c9f256"
  link.split("/")[0, 4].join("/")
end

.object_to_id(object) ⇒ Object



185
186
187
188
189
190
191
192
193
194
# File 'lib/ovirt/base.rb', line 185

def self.object_to_id(object)
  case object
  when Ovirt::Base
    object[:id]
  when String
    href_to_guid(object)
  else
    raise ArgumentError, "object must be a valid guid or an Ovirt Object"
  end
end

.parse_attribute(node, hash, key, modifier = nil) ⇒ Object



48
49
50
51
# File 'lib/ovirt/base.rb', line 48

def self.parse_attribute(node, hash, key, modifier = nil)
  value = node[key.to_s]
  set_value(value, hash, key, modifier)
end

.parse_boolean(what) ⇒ Object



36
37
38
39
40
# File 'lib/ovirt/base.rb', line 36

def self.parse_boolean(what)
  return true  if what == 'true'
  return false if what == 'false'
  raise "Cannot parse boolean for value: <#{what.inspect}>"
end

.parse_first_node(node, path, hash, options) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/ovirt/base.rb', line 63

def self.parse_first_node(node, path, hash, options)
  parse_first_node_with_hash(node, path, nh = {}, options)
  unless nh.empty?
    hash[path.to_sym] = hash[path.to_sym].nil? ? nh : hash[path.to_sym].merge(nh)
  end
  nh
end

.parse_first_node_with_hash(node, path, hash, options) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ovirt/base.rb', line 71

def self.parse_first_node_with_hash(node, path, hash, options)
  xnode = node.xpath(path.to_s).first
  unless xnode.blank?
    options[:attribute].to_a.each      { |key| parse_attribute(xnode, hash, key) }
    options[:attribute_to_i].to_a.each { |key| parse_attribute(xnode, hash, key, :to_i) }
    options[:attribute_to_f].to_a.each { |key| parse_attribute(xnode, hash, key, :to_f) }
    options[:node].to_a.each           { |key| parse_first_text(xnode, hash, key) }
    options[:node_to_i].to_a.each      { |key| parse_first_text(xnode, hash, key, :to_i) }
    options[:node_to_bool].to_a.each   { |key| parse_first_text(xnode, hash, key, :to_bool) }
  end
end

.parse_first_text(node, hash, key, modifier = nil) ⇒ Object



42
43
44
45
46
# File 'lib/ovirt/base.rb', line 42

def self.parse_first_text(node, hash, key, modifier = nil)
  text_node = node.xpath(key.to_s).first
  value     = text_node.text unless text_node.nil?
  set_value(value, hash, key, modifier)
end

.parse_xml(xml) ⇒ Object



127
128
129
130
131
# File 'lib/ovirt/base.rb', line 127

def self.parse_xml(xml)
  node, hash = xml_to_hash(xml)
  parse_node_extended(node, hash) if respond_to?(:parse_node_extended)
  hash
end

.set_value(value, hash, key, modifier) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/ovirt/base.rb', line 53

def self.set_value(value, hash, key, modifier)
  return if value.nil?
  hash[key] = case modifier
              when :to_i    then value.to_i
              when :to_f    then value.to_f
              when :to_bool then parse_boolean(value)
              else value
  end
end

.xml_to_actions(xml) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/ovirt/base.rb', line 20

def self.xml_to_actions(xml)
  node    = xml_to_nokogiri(xml)
  actions = {}
  node.xpath('actions/link').each do |link|
    actions[link['rel'].to_sym] = link['href']
  end

  actions
end

.xml_to_hash(xml) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/ovirt/base.rb', line 133

def self.xml_to_hash(xml)
  node                          = xml_to_nokogiri(xml)
  hash                          = hash_from_id_and_href(node)
  hash[:relationships]          = xml_to_relationships(node)
  hash[:actions]                = xml_to_actions(node)

  top_level_objects.each do |key|
    object_node = node.xpath(key.to_s).first
    hash[key]   = hash_from_id_and_href(object_node) unless object_node.nil?
  end

  top_level_strings.each do |key|
    object_node = node.xpath(key.to_s).first
    hash[key]   = object_node.text unless object_node.nil?
  end

  top_level_integers.each do |key|
    object_node = node.xpath(key.to_s).first
    hash[key]   = object_node.text.to_i  unless object_node.nil?
  end

  top_level_booleans.each do |key|
    object_node = node.xpath(key.to_s).first
    hash[key]   = parse_boolean(object_node.text)  unless object_node.nil?
  end

  top_level_timestamps.each do |key|
    object_node = node.xpath(key.to_s).first
    hash[key]   = Time.parse(object_node.text)  unless object_node.nil?
  end

  return node, hash
end

.xml_to_nokogiri(xml) ⇒ Object



167
168
169
170
171
# File 'lib/ovirt/base.rb', line 167

def self.xml_to_nokogiri(xml)
  return xml if xml.kind_of?(Nokogiri::XML::Element)

  Nokogiri::XML(xml).root
end

.xml_to_relationships(xml) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/ovirt/base.rb', line 10

def self.xml_to_relationships(xml)
  node = xml_to_nokogiri(xml)
  relationships = {}
  node.xpath('link').each do |link|
    relationships[link['rel'].to_sym] = link['href']
  end

  relationships
end

Instance Method Details

#[](key) ⇒ Object



330
331
332
# File 'lib/ovirt/base.rb', line 330

def [](key)
  @attributes[key]
end

#api_endpointObject



306
307
308
# File 'lib/ovirt/base.rb', line 306

def api_endpoint
  self[:href] || "#{self.class.api_endpoint}/#{self[:id]}"
end

#class_suffixObject



302
303
304
# File 'lib/ovirt/base.rb', line 302

def class_suffix
  self.class.name[5..-1]
end

#destroyObject



298
299
300
# File 'lib/ovirt/base.rb', line 298

def destroy
  @service.resource_delete(@attributes[:href])
end

#keysObject



326
327
328
# File 'lib/ovirt/base.rb', line 326

def keys
  @attributes.keys
end

#operation(method, *_args) ⇒ Object



270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/ovirt/base.rb', line 270

def operation(method, *_args)
  if @operations.key?(method.to_sym)
    builder = Nokogiri::XML::Builder.new do |xml|
      xml.action { yield xml if block_given? }
    end
    data = builder.doc.root.to_xml

    @service.resource_post(@operations[method.to_sym], data)
  else
    raise "Method:<#{method}> is not available for object <#{self.class.name}>"
  end
end

#relationship(rel) ⇒ Object



283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/ovirt/base.rb', line 283

def relationship(rel)
  if @relationships.key?(rel.to_sym)
    rel_str  = rel.to_s
    rel_str  = 'storage_domains' if rel_str == 'storagedomains'
    rel_str  = 'data_centers'    if rel_str == 'datacenters'
    singular = rel_str.singularize
    klass    = Ovirt.const_get(singular.camelize)
    xml      = @service.resource_get(@relationships[rel])
    doc      = Nokogiri::XML(xml)
    doc.root.xpath(singular).collect { |node| klass.create_from_xml(@service, node) }
  else
    raise "Relationship:<#{rel}> is not available for object <#{self.class.name}>"
  end
end

#reloadObject



254
255
256
# File 'lib/ovirt/base.rb', line 254

def reload
  replace(self.class.find_by_href(@service, self[:href]))
end

#replace(obj) ⇒ Object



248
249
250
251
252
# File 'lib/ovirt/base.rb', line 248

def replace(obj)
  @relationships = obj.relationships
  @operations    = obj.operations
  @attributes    = obj.attributes
end

#updateObject



317
318
319
320
321
322
323
324
# File 'lib/ovirt/base.rb', line 317

def update
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.send(self.class.namespace.last.downcase) { yield xml if block_given? }
  end
  data = builder.doc.root.to_xml

  @service.resource_put(api_endpoint, data)
end

#update!(&block) ⇒ Object



310
311
312
313
314
315
# File 'lib/ovirt/base.rb', line 310

def update!(&block)
  response = update(&block)

  obj = self.class.create_from_xml(@service, response)
  replace(obj)
end