Class: OVIRT::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/rbovirt.rb,
lib/client/vm_api.rb,
lib/client/host_api.rb,
lib/client/quota_api.rb,
lib/client/cluster_api.rb,
lib/client/template_api.rb,
lib/client/datacenter_api.rb,
lib/client/storage_domain_api.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(username, password, api_entrypoint, options = {}, backward_compatibility_cluster = nil, backward_compatibility_filtered = nil) ⇒ Client

Construct a new ovirt client class. mandatory parameters

username, password, api_entrypoint  - for example 'me@internal', 'secret', 'https://example.com/api'

optional parameters

datacenter_id, cluster_id and filtered_api can be sent in this order for backward
compatibility, or as a hash in the 4th parameter.
datacenter_id - setting the datacenter at initialization will add a default scope to any subsequent call
                to the client to the specified datacenter.
cluster_id    - setting the cluster at initialization will add a default scope to any subsequent call
                to the client to the specified cluster.
filtered_api  - when set to false (default) will use ovirt administrator api, else it will use the user
                api mode.


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rbovirt.rb', line 57

def initialize(username, password, api_entrypoint, options={}, backward_compatibility_cluster=nil, backward_compatibility_filtered=nil )
  if !options.is_a?(Hash)
    # backward compatibility optional parameters
    options = {:datacenter_id => options,
               :cluster_id => backward_compatibility_cluster,
               :filtered_api => backward_compatibility_filtered}
  end
  @api_entrypoint = api_entrypoint
  @credentials    = { :username => username, :password => password }
  @datacenter_id  = options[:datacenter_id]
  @cluster_id     = options[:cluster_id]
  @filtered_api   = options[:filtered_api]
  @ca_cert_file   = options[:ca_cert_file]
  @ca_cert_store  = options[:ca_cert_store]
  @ca_no_verify   = options[:ca_no_verify]
end

Instance Attribute Details

#api_entrypointObject (readonly)

Returns the value of attribute api_entrypoint.



42
43
44
# File 'lib/rbovirt.rb', line 42

def api_entrypoint
  @api_entrypoint
end

#ca_cert_fileObject (readonly)

Returns the value of attribute ca_cert_file.



42
43
44
# File 'lib/rbovirt.rb', line 42

def ca_cert_file
  @ca_cert_file
end

#ca_cert_storeObject (readonly)

Returns the value of attribute ca_cert_store.



42
43
44
# File 'lib/rbovirt.rb', line 42

def ca_cert_store
  @ca_cert_store
end

#ca_no_verifyObject (readonly)

Returns the value of attribute ca_no_verify.



42
43
44
# File 'lib/rbovirt.rb', line 42

def ca_no_verify
  @ca_no_verify
end

#cluster_idObject (readonly)

Returns the value of attribute cluster_id.



42
43
44
# File 'lib/rbovirt.rb', line 42

def cluster_id
  @cluster_id
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



42
43
44
# File 'lib/rbovirt.rb', line 42

def credentials
  @credentials
end

#datacenter_idObject (readonly)

Returns the value of attribute datacenter_id.



42
43
44
# File 'lib/rbovirt.rb', line 42

def datacenter_id
  @datacenter_id
end

#filtered_apiObject (readonly)

Returns the value of attribute filtered_api.



42
43
44
# File 'lib/rbovirt.rb', line 42

def filtered_api
  @filtered_api
end

Instance Method Details

#add_interface(vm_id, opts = {}) ⇒ Object



53
54
55
# File 'lib/client/vm_api.rb', line 53

def add_interface(vm_id, opts={})
  http_post("/vms/%s/nics" % vm_id, OVIRT::Interface.to_xml( opts))
end

#add_volume(vm_id, opts = {}) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/client/vm_api.rb', line 74

def add_volume(vm_id, opts={})
  search = opts[:search] || ("datacenter=%s" % current_datacenter.name)
  opts[:storage_domain_id] = opts[:storage_domain] || storagedomains(:role => 'data', :search => search).first.id
  # If no size is given, default to a volume size of 8GB
  opts[:size] = 8 * 1024 * 1024 * 1024 unless opts[:size]
  opts[:type] = 'data' unless opts[:type]
  opts[:bootable] = 'true' unless opts[:bootable]
  opts[:interface] = 'virtio' unless opts[:interface]
  opts[:format] = 'cow' unless opts[:format]
  opts[:sparse] = 'true' unless opts[:sparse]
  http_post("/vms/%s/disks" % vm_id, OVIRT::Volume.to_xml(opts))
end

#api_versionObject



74
75
76
77
78
# File 'lib/rbovirt.rb', line 74

def api_version
  return @api_version unless @api_version.nil?
  xml = http_get("/")/'/api/product_info/version'
  @api_version = (xml/'version').first[:major] +"."+ (xml/'version').first[:minor]
end

#api_version?(major, minor = nil) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/rbovirt.rb', line 80

def api_version?(major, minor=nil)
  (api_version.split('.')[0] == major) && (minor.nil? ? true : api_version.split('.')[1] == minor)
end

#approve_host(host_id, opts = {}) ⇒ Object



16
17
18
# File 'lib/client/host_api.rb', line 16

def approve_host(host_id, opts={})
    http_post("/hosts/%s/approve" % host_id, "<action></action>")
end

#cluster(cluster_id) ⇒ Object



24
25
26
27
28
# File 'lib/client/cluster_api.rb', line 24

def cluster(cluster_id)
  headers = {:accept => "application/xml; detail=datacenters"}
  cluster_xml = http_get("/clusters/%s" % cluster_id, headers)
  OVIRT::Cluster.new(self, cluster_xml.root)
end

#cluster_version(cluster_id) ⇒ Object



3
4
5
6
# File 'lib/client/cluster_api.rb', line 3

def cluster_version(cluster_id)
  c = cluster(cluster_id)
  return c.version.split('.')[0].to_i, c.version.split('.')[1].to_i
end

#cluster_version?(cluster_id, major) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
11
# File 'lib/client/cluster_api.rb', line 8

def cluster_version?(cluster_id, major)
  c = cluster(cluster_id)
  c.version.split('.')[0] == major
end

#clusters(opts = {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/client/cluster_api.rb', line 13

def clusters(opts={})
  headers = {:accept => "application/xml; detail=datacenters"}
  path = "/clusters"
  path += search_url(opts) unless filtered_api
  http_get(path, headers).xpath('/clusters/cluster').collect do |cl|
    cluster = OVIRT::Cluster.new(self, cl)
    #the following line is needed as a work-around a bug in RHEV 3.0 rest-api
    cluster if filtered_api || (cluster.datacenter.id == current_datacenter.id)
  end.compact
end

#create_template(opts) ⇒ Object



17
18
19
20
# File 'lib/client/template_api.rb', line 17

def create_template(opts)
  template = http_post("/templates", Template.to_xml(opts))
  OVIRT::Template::new(self, template.root)
end

#create_vm(opts) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/client/vm_api.rb', line 17

def create_vm(opts)
  cluster_major_ver, cluster_minor_ver = cluster_version(self.cluster_id)

  if opts[:user_data] and not opts[:user_data].empty?
    if api_version?('3') and cluster_major_ver >= 3
      if cluster_minor_ver >= 1
        opts[:user_data_method] = :payload
      elsif floppy_hook?
        opts[:user_data_method] = :custom_property
      else
        raise "Required VDSM hook 'floppyinject' not supported by RHEV-M"
      end
    else
      raise BackendVersionUnsupportedException.new
    end
  end

  opts[:cluster_name] ||= clusters.first.name unless opts[:cluster]
  OVIRT::VM::new(self, http_post("/vms",OVIRT::VM.to_xml(opts)).root)
end

#datacenter(datacenter_id) ⇒ Object



3
4
5
6
7
8
9
10
# File 'lib/client/datacenter_api.rb', line 3

def datacenter(datacenter_id)
  begin
    datacenter = http_get("/datacenters/%s" % datacenter_id)
    OVIRT::DataCenter::new(self, datacenter.root)
  rescue
    handle_fault $!
  end
end

#datacenters(opts = {}) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/client/datacenter_api.rb', line 12

def datacenters(opts={})
  search = opts[:search] ||""
  datacenters = http_get("/datacenters?search=%s" % CGI.escape(search))
  datacenters.xpath('/data_centers/data_center').collect do |dc|
    OVIRT::DataCenter::new(self, dc)
  end
end

#destroy_interface(vm_id, interface_id) ⇒ Object



49
50
51
# File 'lib/client/vm_api.rb', line 49

def destroy_interface(vm_id, interface_id)
  http_delete("/vms/%s/nics/%s" % [vm_id, interface_id])
end

#destroy_template(id) ⇒ Object



22
23
24
# File 'lib/client/template_api.rb', line 22

def destroy_template(id)
  http_delete("/templates/%s" % id)
end

#destroy_vm(id) ⇒ Object



106
107
108
# File 'lib/client/vm_api.rb', line 106

def destroy_vm(id)
  http_delete("/vms/%s" % id)
end

#destroy_volume(vm_id, vol_id) ⇒ Object



87
88
89
# File 'lib/client/vm_api.rb', line 87

def destroy_volume(vm_id, vol_id)
  http_delete("/vms/%s/disks/%s" % [vm_id, vol_id])
end

#floppy_hook?Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/rbovirt.rb', line 84

def floppy_hook?
  xml = http_get("/capabilities")
  !(xml/"version/custom_properties/custom_property[@name='floppyinject']").empty?
end

#host(host_id, opts = {}) ⇒ Object



3
4
5
6
# File 'lib/client/host_api.rb', line 3

def host(host_id, opts={})
  xml_response = http_get("/hosts/%s" % host_id)
  OVIRT::Host::new(self, xml_response.root)
end

#hosts(opts = {}) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/client/host_api.rb', line 8

def hosts(opts={})
  path = "/hosts"
  path += search_url(opts) unless filtered_api
  http_get(path).xpath('/hosts/host').collect do |h|
    OVIRT::Host::new(self, h)
  end
end

#networks(opts) ⇒ Object



30
31
32
33
34
35
# File 'lib/client/cluster_api.rb', line 30

def networks(opts)
  cluster_id = opts[:cluster_id] || current_cluster.id
  http_get("/clusters/%s/networks" % cluster_id, http_headers).xpath('/networks/network').collect do |cl|
    OVIRT::Network.new(self, cl)
  end
end

#quota(quota_id, opts = {}) ⇒ Object



3
4
5
6
# File 'lib/client/quota_api.rb', line 3

def quota(quota_id, opts={})
  q = http_get("/datacenters/%s/quotas/%s" % [current_datacenter.id, quota_id])
  OVIRT::Quota::new(self, q.root)
end

#quotas(opts = {}) ⇒ Object



8
9
10
11
12
# File 'lib/client/quota_api.rb', line 8

def quotas(opts={})
  http_get("/datacenters/%s/quotas" % CGI.escape(current_datacenter.id)).xpath('/quotas/quota').collect do |q|
    OVIRT::Quota::new(self, q)
  end.compact
end

#reinstall_host(host_id, opts = {}) ⇒ Object



20
21
22
23
24
25
# File 'lib/client/host_api.rb', line 20

def reinstall_host(host_id, opts={})
    http_post("/hosts/%s/install" % host_id,
              "<action><ssh>
               <authentication_method>PublicKey</authentication_method>
               </ssh></action>")
end

#set_ticket(vm_id, options = {}) ⇒ Object



110
111
112
113
114
# File 'lib/client/vm_api.rb', line 110

def set_ticket(vm_id, options={})
  ticket = OVIRT::VM.ticket(options)
  xml_response = http_post("/vms/%s/ticket" % vm_id, ticket)
  (xml_response/'action/ticket/value').first.text
end

#storagedomain(sd_id) ⇒ Object



3
4
5
6
# File 'lib/client/storage_domain_api.rb', line 3

def storagedomain(sd_id)
  sd = http_get("/storagedomains/%s" % sd_id)
  OVIRT::StorageDomain::new(self, sd.root)
end

#storagedomains(opts = {}) ⇒ Object



8
9
10
11
12
13
14
15
16
# File 'lib/client/storage_domain_api.rb', line 8

def storagedomains(opts={})
  path = "/storagedomains"
  path += search_url(opts) unless filtered_api
  http_get(path).xpath('/storage_domains/storage_domain').collect do |sd|
    storage_domain = OVIRT::StorageDomain::new(self, sd)
    #filter by role is not supported by the search language. The work around is to list all, then filter.
    (opts[:role].nil? || storage_domain.role == opts[:role]) ? storage_domain : nil
  end.compact
end

#template(template_id, opts = {}) ⇒ Object



11
12
13
14
15
# File 'lib/client/template_api.rb', line 11

def template(template_id, opts={})
  results = http_get("/templates/%s" % template_id)
  template = OVIRT::Template::new(self, results.root)
  template
end

#template_interfaces(template_id) ⇒ Object



26
27
28
29
30
# File 'lib/client/template_api.rb', line 26

def template_interfaces template_id
  http_get("/templates/%s/nics" % template_id, http_headers).xpath('/nics/nic').collect do |nic|
    OVIRT::Interface::new(self, nic)
  end
end

#template_volumes(template_id) ⇒ Object



32
33
34
35
36
# File 'lib/client/template_api.rb', line 32

def template_volumes template_id
  http_get("/templates/%s/disks" % template_id, http_headers).xpath('/disks/disk').collect do |disk|
    OVIRT::Volume::new(self, disk)
  end
end

#templates(opts = {}) ⇒ Object



3
4
5
6
7
8
9
# File 'lib/client/template_api.rb', line 3

def templates(opts={})
  path = "/templates"
  path += search_url(opts) unless filtered_api
  http_get(path).xpath('/templates/template').collect do |t|
    OVIRT::Template::new(self, t)
  end.compact
end

#update_interface(vm_id, interface_id, opts = {}) ⇒ Object



57
58
59
# File 'lib/client/vm_api.rb', line 57

def update_interface(vm_id, interface_id, opts={})
  http_put("/vms/%s/nics/%s" % [vm_id, interface_id], OVIRT::Interface.to_xml( opts))
end

#update_vm(opts) ⇒ Object



116
117
118
119
120
# File 'lib/client/vm_api.rb', line 116

def update_vm(opts)
  opts[:cluster_name] ||= clusters.first.name
  result_xml = http_put("/vms/%s" % opts[:id], OVIRT::VM.to_xml(opts))
  OVIRT::VM::new(self, result_xml.root)
end

#update_volume(vm_id, vol_id, opts = {}) ⇒ Object



91
92
93
# File 'lib/client/vm_api.rb', line 91

def update_volume(vm_id, vol_id, opts={})
  http_put("/vms/%s/disks/%s" % [vm_id, vol_id], OVIRT::Volume.to_xml(opts))
end

#vm(vm_id, opts = {}) ⇒ Object



3
4
5
6
# File 'lib/client/vm_api.rb', line 3

def vm(vm_id, opts={})
  headers = {:accept => "application/xml; detail=disks; detail=nics; detail=hosts"}
  OVIRT::VM::new(self,  http_get("/vms/%s" % vm_id, headers).root)
end

#vm_action(id, action, opts = {}) ⇒ Object



95
96
97
98
# File 'lib/client/vm_api.rb', line 95

def vm_action(id, action, opts={})
  xml_response = http_post("/vms/%s/%s" % [id, action],'<action/>', opts)
  return (xml_response/'action/status').first.text.strip.upcase=="COMPLETE"
end

#vm_interfaces(vm_id) ⇒ Object



38
39
40
41
42
43
44
45
46
47
# File 'lib/client/vm_api.rb', line 38

def vm_interfaces vm_id
  begin
    http_get("/vms/%s/nics" % vm_id, http_headers).xpath('/nics/nic').collect do |nic|
      OVIRT::Interface::new(self, nic)
    end
  rescue => e # Catch case were vm_id is destroyed.
    raise e unless e.message =~ /Entity not found/
    []
  end
end

#vm_start_with_cloudinit(id, opts = {}) ⇒ Object



100
101
102
103
104
# File 'lib/client/vm_api.rb', line 100

def vm_start_with_cloudinit(id, opts={})
  xml = OVIRT::VM.cloudinit(opts)
  xml_response = http_post("/vms/%s/%s" % [id, 'start'], xml, {} )
  return (xml_response/'action/status').first.text.strip.upcase=="COMPLETE"
end

#vm_volumes(vm_id) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/client/vm_api.rb', line 61

def vm_volumes vm_id
  begin
    volumes = http_get("/vms/%s/disks" % vm_id, http_headers).xpath('/disks/disk').collect do |disk|
      OVIRT::Volume::new(self, disk)
    end
  rescue => e # Catch case were vm_id is destroyed.
    raise e unless e.message =~ /Entity not found/
    volumes = []
  end
  #this is a workaround to a bug that the list is not sorted by default.
  volumes.sort{ |l, r| l.name <=> r.name }
end

#vms(opts = {}) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/client/vm_api.rb', line 8

def vms(opts={})
  headers = {:accept => "application/xml; detail=disks; detail=nics; detail=hosts"}
  path = "/vms"
  path += search_url(opts) unless filtered_api
  http_get(path, headers).xpath('/vms/vm').collect do |vm|
    OVIRT::VM::new(self, vm)
  end
end