fog-opennebula 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +32 -0
- data/CONTRIBUTORS.md +4 -0
- data/Gemfile +9 -0
- data/LICENSE.md +20 -0
- data/README.md +95 -0
- data/Rakefile +118 -0
- data/fog-opennebula.gemspec +35 -0
- data/lib/fog/bin/opennebula.rb +32 -0
- data/lib/fog/opennebula.rb +30 -0
- data/lib/fog/opennebula/compute.rb +136 -0
- data/lib/fog/opennebula/models/compute/flavor.rb +190 -0
- data/lib/fog/opennebula/models/compute/flavors.rb +46 -0
- data/lib/fog/opennebula/models/compute/group.rb +28 -0
- data/lib/fog/opennebula/models/compute/groups.rb +38 -0
- data/lib/fog/opennebula/models/compute/interface.rb +39 -0
- data/lib/fog/opennebula/models/compute/interfaces.rb +20 -0
- data/lib/fog/opennebula/models/compute/network.rb +48 -0
- data/lib/fog/opennebula/models/compute/networks.rb +42 -0
- data/lib/fog/opennebula/models/compute/server.rb +85 -0
- data/lib/fog/opennebula/models/compute/servers.rb +33 -0
- data/lib/fog/opennebula/requests/compute/OpenNebulaVNC.rb +314 -0
- data/lib/fog/opennebula/requests/compute/get_vnc_console.rb +58 -0
- data/lib/fog/opennebula/requests/compute/image_pool.rb +33 -0
- data/lib/fog/opennebula/requests/compute/list_groups.rb +87 -0
- data/lib/fog/opennebula/requests/compute/list_networks.rb +79 -0
- data/lib/fog/opennebula/requests/compute/list_vms.rb +79 -0
- data/lib/fog/opennebula/requests/compute/template_pool.rb +120 -0
- data/lib/fog/opennebula/requests/compute/vm_allocate.rb +97 -0
- data/lib/fog/opennebula/requests/compute/vm_destroy.rb +39 -0
- data/lib/fog/opennebula/requests/compute/vm_disk_snapshot.rb +33 -0
- data/lib/fog/opennebula/requests/compute/vm_resume.rb +35 -0
- data/lib/fog/opennebula/requests/compute/vm_shutdown.rb +22 -0
- data/lib/fog/opennebula/requests/compute/vm_stop.rb +21 -0
- data/lib/fog/opennebula/requests/compute/vm_suspend.rb +38 -0
- data/lib/fog/opennebula/version.rb +9 -0
- data/tests/opennebula/compute_tests.rb +15 -0
- data/tests/opennebula/models/compute/flavor_tests.rb +34 -0
- data/tests/opennebula/models/compute/flavors_tests.rb +15 -0
- data/tests/opennebula/models/compute/group_tests.rb +25 -0
- data/tests/opennebula/models/compute/groups_tests.rb +14 -0
- data/tests/opennebula/models/compute/network_tests.rb +24 -0
- data/tests/opennebula/models/compute/networks_tests.rb +14 -0
- data/tests/opennebula/requests/compute/vm_allocate_tests.rb +70 -0
- data/tests/opennebula/requests/compute/vm_disk_snapshot_test.rb +44 -0
- data/tests/opennebula/requests/compute/vm_suspend_resume_tests.rb +45 -0
- metadata +243 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def image_pool(filter = {})
|
10
|
+
images = ::OpenNebula::ImagePool.new(client)
|
11
|
+
if filter[:mine].nil?
|
12
|
+
images.info!
|
13
|
+
else
|
14
|
+
images.info_mine!
|
15
|
+
end
|
16
|
+
|
17
|
+
unless filter[:id].nil?
|
18
|
+
images.each do |i|
|
19
|
+
if filter[:id] == i.id
|
20
|
+
return [i] # return an array with only one element - found image
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
images
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def list_groups(filter = {})
|
10
|
+
groups = []
|
11
|
+
grouppool = ::OpenNebula::GroupPool.new(client)
|
12
|
+
grouppool.info
|
13
|
+
|
14
|
+
# {
|
15
|
+
# "GROUP"=>{
|
16
|
+
# "ID"=>"0",
|
17
|
+
# "NAME"=>"oneadmin",
|
18
|
+
# "USERS"=>{"ID"=>["0", "1"]},
|
19
|
+
# "DATASTORE_QUOTA"=>{},
|
20
|
+
# "NETWORK_QUOTA"=>{},
|
21
|
+
# "VM_QUOTA"=>{},
|
22
|
+
# "IMAGE_QUOTA"=>{}
|
23
|
+
# }
|
24
|
+
# }
|
25
|
+
|
26
|
+
grouppool.each do |group|
|
27
|
+
filter_missmatch = false
|
28
|
+
|
29
|
+
unless filter.empty?
|
30
|
+
filter.each do |k, v|
|
31
|
+
if group[k.to_s.upcase.to_s] && group[k.to_s.upcase.to_s] != v.to_s
|
32
|
+
filter_missmatch = true
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
36
|
+
next if filter_missmatch
|
37
|
+
end
|
38
|
+
groups << { :id => group['ID'], :name => group['NAME'] }
|
39
|
+
end
|
40
|
+
groups
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class Mock
|
46
|
+
|
47
|
+
def list_groups(filter = {})
|
48
|
+
groups = []
|
49
|
+
net1 = mock_group '1', 'net1'
|
50
|
+
net2 = mock_group '2', 'fogtest'
|
51
|
+
|
52
|
+
grouppool = [net1, net2]
|
53
|
+
grouppool.each do |group|
|
54
|
+
filter_missmatch = false
|
55
|
+
|
56
|
+
unless filter.empty?
|
57
|
+
filter.each do |k, v|
|
58
|
+
if group[k.to_s.upcase.to_s] && group[k.to_s.upcase.to_s] != v.to_s
|
59
|
+
filter_missmatch = true
|
60
|
+
break
|
61
|
+
end
|
62
|
+
end
|
63
|
+
next if filter_missmatch
|
64
|
+
end
|
65
|
+
groups << { :id => group['ID'], :name => group['NAME'] }
|
66
|
+
end
|
67
|
+
groups
|
68
|
+
end
|
69
|
+
|
70
|
+
def mock_group(id, name)
|
71
|
+
{
|
72
|
+
'ID' => id,
|
73
|
+
'NAME' => name,
|
74
|
+
'UID' => '5',
|
75
|
+
'GID' => '5',
|
76
|
+
'DESCRIPTION' => 'netDescription',
|
77
|
+
'VLAN' => '5'
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def list_networks(filter = {})
|
10
|
+
networks = []
|
11
|
+
netpool = ::OpenNebula::VirtualNetworkPool.new(client)
|
12
|
+
if filter[:id].nil?
|
13
|
+
netpool.info!(-2, -1, -1)
|
14
|
+
elsif filter[:id]
|
15
|
+
filter[:id] = filter[:id].to_i if filter[:id].is_a?(String)
|
16
|
+
netpool.info!(-2, filter[:id], filter[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
netpool.each do |network|
|
20
|
+
if filter[:network] && filter[:network].is_a?(String) && !filter[:network].empty?
|
21
|
+
next if network.to_hash['VNET']['NAME'] != filter[:network]
|
22
|
+
end
|
23
|
+
if filter[:network_uname] && filter[:network_uname].is_a?(String) && !filter[:network_uname].empty?
|
24
|
+
next if network.to_hash['VNET']['UNAME'] != filter[:network_uname]
|
25
|
+
end
|
26
|
+
if filter[:network_uid] && filter[:network_uid].is_a?(String) && !filter[:network_uid].empty?
|
27
|
+
next if network.to_hash['VNET']['UID'] != filter[:network_uid]
|
28
|
+
end
|
29
|
+
networks << network_to_attributes(network.to_hash)
|
30
|
+
end
|
31
|
+
networks
|
32
|
+
end
|
33
|
+
|
34
|
+
def network_to_attributes(net)
|
35
|
+
return if net.nil?
|
36
|
+
|
37
|
+
h = {
|
38
|
+
:id => net['VNET']['ID'],
|
39
|
+
:name => net['VNET']['NAME'],
|
40
|
+
:uid => net['VNET']['UID'],
|
41
|
+
:uname => net['VNET']['UNAME'],
|
42
|
+
:gid => net['VNET']['GID']
|
43
|
+
}
|
44
|
+
|
45
|
+
h[:description] = net['VNET']['TEMPLATE']['DESCRIPTION'] unless net['VNET']['TEMPLATE']['DESCRIPTION'].nil?
|
46
|
+
h[:vlan] = net['VNET']['VLAN_ID'] unless net['VNET']['VLAN_ID'].nil? || net['VNET']['VLAN_ID'].empty?
|
47
|
+
|
48
|
+
h
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
class Mock
|
54
|
+
|
55
|
+
def list_networks(_filters = {})
|
56
|
+
net1 = mock_network 'fogtest'
|
57
|
+
net2 = mock_network 'net2'
|
58
|
+
[net1, net2]
|
59
|
+
end
|
60
|
+
|
61
|
+
def mock_network(name)
|
62
|
+
{
|
63
|
+
:id => '5',
|
64
|
+
:name => name,
|
65
|
+
:uid => '5',
|
66
|
+
:uname => 'mock',
|
67
|
+
:gid => '5',
|
68
|
+
:description => 'netDescription',
|
69
|
+
:vlan => '5'
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def list_vms(filter = {})
|
10
|
+
vms = []
|
11
|
+
vmpool = ::OpenNebula::VirtualMachinePool.new(client)
|
12
|
+
if filter[:id].nil?
|
13
|
+
vmpool.info(-2, -1, -1, -1)
|
14
|
+
elsif filter[:id]
|
15
|
+
filter[:id] = filter[:id].to_i if filter[:id].is_a?(String)
|
16
|
+
vmpool.info(-2, filter[:id], filter[:id], -1)
|
17
|
+
end
|
18
|
+
|
19
|
+
vmpool.each do |vm|
|
20
|
+
one = vm.to_hash
|
21
|
+
data = {}
|
22
|
+
data['onevm_object'] = vm
|
23
|
+
data['status'] = vm.state
|
24
|
+
data['state'] = vm.lcm_state_str
|
25
|
+
data['id'] = vm.id
|
26
|
+
data['gid'] = vm.gid
|
27
|
+
data['uuid'] = vm.id
|
28
|
+
data['name'] = one['VM']['NAME'] unless one['VM']['NAME'].nil?
|
29
|
+
data['user'] = one['VM']['UNAME'] unless one['VM']['UNAME'].nil?
|
30
|
+
data['group'] = one['VM']['GNAME'] unless one['VM']['GNAME'].nil?
|
31
|
+
|
32
|
+
unless one['VM']['TEMPLATE'].nil?
|
33
|
+
data['cpu'] = one['VM']['TEMPLATE']['VCPU'] unless one['VM']['TEMPLATE']['VCPU'].nil?
|
34
|
+
data['memory'] = one['VM']['TEMPLATE']['MEMORY'] unless one['VM']['TEMPLATE']['MEMORY'].nil?
|
35
|
+
unless one['VM']['TEMPLATE']['NIC'].nil?
|
36
|
+
if one['VM']['TEMPLATE']['NIC'].is_a?(Array)
|
37
|
+
data['ip'] = one['VM']['TEMPLATE']['NIC'][0]['IP']
|
38
|
+
data['mac'] = one['VM']['TEMPLATE']['NIC'][0]['MAC']
|
39
|
+
else
|
40
|
+
data['ip'] = one['VM']['TEMPLATE']['NIC']['IP'] unless one['VM']['TEMPLATE']['NIC']['IP'].nil?
|
41
|
+
data['mac'] = one['VM']['TEMPLATE']['NIC']['MAC'] unless one['VM']['TEMPLATE']['NIC']['MAC'].nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
vms << data
|
47
|
+
end
|
48
|
+
vms
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
module Shared
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class Mock
|
60
|
+
|
61
|
+
def list_vms(filter = {})
|
62
|
+
vms = []
|
63
|
+
data['vms'].each do |vm|
|
64
|
+
if filter[:id].nil?
|
65
|
+
vms << vm
|
66
|
+
elsif filter[:id] == vm['id']
|
67
|
+
vms << vm
|
68
|
+
end
|
69
|
+
end
|
70
|
+
vms
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def template_pool(filter = {})
|
10
|
+
templates = ::OpenNebula::TemplatePool.new(client)
|
11
|
+
if filter[:id].nil?
|
12
|
+
templates.info!(-2, -1, -1)
|
13
|
+
elsif filter[:id]
|
14
|
+
filter[:id] = filter[:id].to_i if filter[:id].is_a?(String)
|
15
|
+
templates.info!(-2, filter[:id], filter[:id])
|
16
|
+
end
|
17
|
+
|
18
|
+
templates = templates.map do |t|
|
19
|
+
# filtering by name
|
20
|
+
# done here, because OpenNebula:TemplatePool does not support something like .delete_if
|
21
|
+
if filter[:name] && filter[:name].is_a?(String) && !filter[:name].empty?
|
22
|
+
next if t.to_hash['VMTEMPLATE']['NAME'] != filter[:name]
|
23
|
+
end
|
24
|
+
if filter[:uname] && filter[:uname].is_a?(String) && !filter[:uname].empty?
|
25
|
+
next if t.to_hash['VMTEMPLATE']['UNAME'] != filter[:uname]
|
26
|
+
end
|
27
|
+
if filter[:uid] && filter[:uid].is_a?(String) && !filter[:uid].empty?
|
28
|
+
next if t.to_hash['VMTEMPLATE']['UID'] != filter[:uid]
|
29
|
+
end
|
30
|
+
|
31
|
+
h = Hash[
|
32
|
+
:id => t.to_hash['VMTEMPLATE']['ID'],
|
33
|
+
:name => t.to_hash['VMTEMPLATE']['NAME'],
|
34
|
+
:content => t.template_str,
|
35
|
+
:USER_VARIABLES => '' # Default if not set in template
|
36
|
+
]
|
37
|
+
h.merge! t.to_hash['VMTEMPLATE']['TEMPLATE']
|
38
|
+
|
39
|
+
# h["NIC"] has to be an array of nic objects
|
40
|
+
nics = h['NIC'] unless h['NIC'].nil?
|
41
|
+
h['NIC'] = [] # reset nics to a array
|
42
|
+
if nics.is_a? Array
|
43
|
+
nics.each do |n|
|
44
|
+
if n['NETWORK_ID']
|
45
|
+
vnet = networks.get(n['NETWORK_ID'].to_s)
|
46
|
+
elsif n['NETWORK']
|
47
|
+
vnet = networks.get_by_name(n['NETWORK'].to_s)
|
48
|
+
else
|
49
|
+
next
|
50
|
+
end
|
51
|
+
h['NIC'] << interfaces.new(:vnet => vnet, :model => n['MODEL'] || 'virtio')
|
52
|
+
end
|
53
|
+
elsif nics.is_a? Hash
|
54
|
+
nics['model'] = 'virtio' if nics['model'].nil?
|
55
|
+
# nics["uuid"] = "0" if nics["uuid"].nil? # is it better is to remove this NIC?
|
56
|
+
n = networks.get_by_filter(
|
57
|
+
:id => nics['NETWORK_ID'],
|
58
|
+
:network => nics['NETWORK'],
|
59
|
+
:network_uname => nics['NETWORK_UNAME'],
|
60
|
+
:network_uid => nics['NETWORK_UID']
|
61
|
+
)
|
62
|
+
n.each do |i|
|
63
|
+
h['NIC'] << interfaces.new(:vnet => i)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# every key should be lowercase
|
68
|
+
ret_hash = {}
|
69
|
+
h.each_pair do |k, v|
|
70
|
+
ret_hash.merge!(k.downcase => v)
|
71
|
+
end
|
72
|
+
ret_hash
|
73
|
+
end
|
74
|
+
|
75
|
+
templates.delete nil
|
76
|
+
raise Fog::Compute::OpenNebula::NotFound, 'Flavor/Template not found' if templates.empty?
|
77
|
+
|
78
|
+
templates
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class Mock
|
84
|
+
|
85
|
+
def template_pool(_filter = {})
|
86
|
+
nic1 = Mock_nic.new
|
87
|
+
nic1.vnet = networks.first
|
88
|
+
|
89
|
+
data['template_pool']
|
90
|
+
data['template_pool'].each do |tmpl|
|
91
|
+
tmpl['nic'][0] = nic1
|
92
|
+
end
|
93
|
+
data['template_pool']
|
94
|
+
end
|
95
|
+
|
96
|
+
class Mock_nic
|
97
|
+
|
98
|
+
attr_accessor :vnet
|
99
|
+
|
100
|
+
def id
|
101
|
+
2
|
102
|
+
end
|
103
|
+
|
104
|
+
def name
|
105
|
+
'fogtest'
|
106
|
+
end
|
107
|
+
|
108
|
+
def model
|
109
|
+
'virtio-net'
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Fog
|
2
|
+
|
3
|
+
module Compute
|
4
|
+
|
5
|
+
class OpenNebula
|
6
|
+
|
7
|
+
class Real
|
8
|
+
|
9
|
+
def vm_allocate(attr = {})
|
10
|
+
if attr[:flavor].nil?
|
11
|
+
raise ArgumentError, "Attribute flavor is nil! #{attr.inspect}"
|
12
|
+
end
|
13
|
+
if attr[:name].nil? || attr[:name].empty?
|
14
|
+
raise ArgumentError, "Attribute name is nil or empty! #{attr.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
xml = ::OpenNebula::VirtualMachine.build_xml
|
18
|
+
vm = ::OpenNebula::VirtualMachine.new(xml, client)
|
19
|
+
rc = vm.allocate(attr[:flavor].to_s + "\nNAME=\"" + attr[:name] + '"')
|
20
|
+
|
21
|
+
raise(rc) if rc.is_a? ::OpenNebula::Error
|
22
|
+
|
23
|
+
# -1 - do not change the owner
|
24
|
+
vm.chown(-1, attr[:gid].to_i) unless attr[:gid].nil?
|
25
|
+
|
26
|
+
# TODO
|
27
|
+
# check if vm is created vmid.class == One error class
|
28
|
+
vm.info!
|
29
|
+
|
30
|
+
one = vm.to_hash
|
31
|
+
data = {}
|
32
|
+
data['onevm_object'] = vm
|
33
|
+
data['status'] = vm.state
|
34
|
+
data['state'] = vm.lcm_state_str
|
35
|
+
data['id'] = vm.id
|
36
|
+
data['uuid'] = vm.id
|
37
|
+
data['gid'] = vm.gid
|
38
|
+
data['name'] = one['VM']['NAME'] unless one['VM']['NAME'].nil?
|
39
|
+
data['user'] = one['VM']['UNAME'] unless one['VM']['UNAME'].nil?
|
40
|
+
data['group'] = one['VM']['GNAME'] unless one['VM']['GNAME'].nil?
|
41
|
+
|
42
|
+
unless one['VM']['TEMPLATE'].nil?
|
43
|
+
temp = one['VM']['TEMPLATE']
|
44
|
+
data['cpu'] = temp['VCPU'] unless temp['VCPU'].nil?
|
45
|
+
data['memory'] = temp['MEMORY'] unless temp['MEMORY'].nil?
|
46
|
+
unless temp['NIC'].nil?
|
47
|
+
if one['VM']['TEMPLATE']['NIC'].is_a?(Array)
|
48
|
+
data['mac'] = temp['NIC'][0]['MAC'] unless temp['NIC'][0]['MAC'].nil?
|
49
|
+
data['ip'] = temp['NIC'][0]['IP'] unless temp['NIC'][0]['IP'].nil?
|
50
|
+
else
|
51
|
+
data['mac'] = temp['NIC']['MAC'] unless temp['NIC']['MAC'].nil?
|
52
|
+
data['ip'] = temp['NIC']['IP'] unless temp['NIC']['IP'].nil?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
data
|
58
|
+
rescue StandardError => err
|
59
|
+
raise(err)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class Mock
|
65
|
+
|
66
|
+
def vm_allocate(attr = {})
|
67
|
+
response = Excon::Response.new
|
68
|
+
response.status = 200
|
69
|
+
|
70
|
+
id = rand(1000)
|
71
|
+
ids = []
|
72
|
+
|
73
|
+
data['vms'].each do |vm|
|
74
|
+
ids << vm['id']
|
75
|
+
next unless vm['id'] == id
|
76
|
+
|
77
|
+
id = rand(1000) while ids.include?(id)
|
78
|
+
break
|
79
|
+
end
|
80
|
+
|
81
|
+
data = {}
|
82
|
+
data['id'] = id
|
83
|
+
data['flavor'] = attr[:flavor]
|
84
|
+
data['name'] = attr[:name]
|
85
|
+
data['state'] = 'RUNNING'
|
86
|
+
data['status'] = 3
|
87
|
+
self.data['vms'] << data
|
88
|
+
data
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|