opennebula-oca 3.8.0 → 3.9.0.beta
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.
- data/lib/{OpenNebula/Acl.rb → opennebula/acl.rb} +0 -0
- data/lib/{OpenNebula/AclPool.rb → opennebula/acl_pool.rb} +1 -1
- data/lib/{OpenNebula.rb → opennebula/client.rb} +0 -73
- data/lib/{OpenNebula/Cluster.rb → opennebula/cluster.rb} +1 -1
- data/lib/{OpenNebula/ClusterPool.rb → opennebula/cluster_pool.rb} +1 -1
- data/lib/{OpenNebula/Datastore.rb → opennebula/datastore.rb} +23 -1
- data/lib/{OpenNebula/DatastorePool.rb → opennebula/datastore_pool.rb} +1 -1
- data/lib/{OpenNebula/Document.rb → opennebula/document.rb} +13 -2
- data/lib/{OpenNebula/DocumentJSON.rb → opennebula/document_json.rb} +0 -0
- data/lib/{OpenNebula/DocumentPool.rb → opennebula/document_pool.rb} +2 -2
- data/lib/{OpenNebula/DocumentPoolJSON.rb → opennebula/document_pool_json.rb} +0 -0
- data/lib/opennebula/error.rb +52 -0
- data/lib/{OpenNebula/Group.rb → opennebula/group.rb} +1 -1
- data/lib/{OpenNebula/GroupPool.rb → opennebula/group_pool.rb} +1 -1
- data/lib/{OpenNebula/Host.rb → opennebula/host.rb} +1 -1
- data/lib/{OpenNebula/HostPool.rb → opennebula/host_pool.rb} +1 -1
- data/lib/{OpenNebula/Image.rb → opennebula/image.rb} +20 -6
- data/lib/{OpenNebula/ImagePool.rb → opennebula/image_pool.rb} +1 -1
- data/lib/opennebula/ldap_auth.rb +99 -0
- data/lib/opennebula/ldap_auth_spec.rb +70 -0
- data/lib/opennebula/pool.rb +157 -0
- data/lib/{OpenNebula/Pool.rb → opennebula/pool_element.rb} +1 -138
- data/lib/opennebula/server_cipher_auth.rb +148 -0
- data/lib/opennebula/server_x509_auth.rb +104 -0
- data/lib/opennebula/ssh_auth.rb +139 -0
- data/lib/opennebula/system.rb +141 -0
- data/lib/{OpenNebula/Template.rb → opennebula/template.rb} +13 -2
- data/lib/{OpenNebula/TemplatePool.rb → opennebula/template_pool.rb} +1 -1
- data/lib/{OpenNebula/User.rb → opennebula/user.rb} +1 -1
- data/lib/{OpenNebula/UserPool.rb → opennebula/user_pool.rb} +1 -1
- data/lib/{OpenNebula/VirtualMachine.rb → opennebula/virtual_machine.rb} +45 -25
- data/lib/{OpenNebula/VirtualMachinePool.rb → opennebula/virtual_machine_pool.rb} +1 -1
- data/lib/{OpenNebula/VirtualNetwork.rb → opennebula/virtual_network.rb} +13 -2
- data/lib/{OpenNebula/VirtualNetworkPool.rb → opennebula/virtual_network_pool.rb} +1 -1
- data/lib/opennebula/x509_auth.rb +241 -0
- data/lib/{OpenNebula/XMLUtils.rb → opennebula/xml_element.rb} +12 -21
- data/lib/opennebula/xml_pool.rb +45 -0
- data/lib/opennebula/xml_utils.rb +34 -0
- data/lib/opennebula.rb +58 -0
- metadata +102 -63
@@ -0,0 +1,141 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
|
3
|
+
# #
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
6
|
+
# a copy of the License at #
|
7
|
+
# #
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
9
|
+
# #
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
13
|
+
# See the License for the specific language governing permissions and #
|
14
|
+
# limitations under the License. #
|
15
|
+
#--------------------------------------------------------------------------- #
|
16
|
+
|
17
|
+
|
18
|
+
require 'opennebula/pool'
|
19
|
+
|
20
|
+
module OpenNebula
|
21
|
+
class System
|
22
|
+
#######################################################################
|
23
|
+
# Constants and Class attribute accessors
|
24
|
+
#######################################################################
|
25
|
+
|
26
|
+
SYSTEM_METHODS = {
|
27
|
+
:userquotainfo => "userquota.info",
|
28
|
+
:userquotaupdate => "userquota.update",
|
29
|
+
:groupquotainfo => "groupquota.info",
|
30
|
+
:groupquotaupdate => "groupquota.update",
|
31
|
+
:version => "system.version",
|
32
|
+
:config => "system.config"
|
33
|
+
}
|
34
|
+
|
35
|
+
#######################################################################
|
36
|
+
# Class constructor
|
37
|
+
#######################################################################
|
38
|
+
|
39
|
+
# Constructor
|
40
|
+
# @param [Client] client that represents a XML-RPC connection
|
41
|
+
def initialize(client)
|
42
|
+
@client = client
|
43
|
+
end
|
44
|
+
|
45
|
+
#######################################################################
|
46
|
+
# XML-RPC Methods
|
47
|
+
#######################################################################
|
48
|
+
|
49
|
+
# Gets the oned version
|
50
|
+
#
|
51
|
+
# @return [String, OpenNebula::Error] the oned version in case
|
52
|
+
# of success, Error otherwise
|
53
|
+
def get_oned_version()
|
54
|
+
return @client.call("system.version")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns whether of not the oned version is the same as the OCA version
|
58
|
+
#
|
59
|
+
# @return [true, false, OpenNebula::Error] true if oned is the same
|
60
|
+
# version
|
61
|
+
def compatible_version()
|
62
|
+
no_revision = VERSION[/^\d+\.\d+\./]
|
63
|
+
oned_v = get_oned_version
|
64
|
+
|
65
|
+
if OpenNebula.is_error?(oned_v)
|
66
|
+
return oned_v
|
67
|
+
end
|
68
|
+
|
69
|
+
return (oned_v =~ /#{no_revision}/) != nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# Gets the oned configuration
|
73
|
+
#
|
74
|
+
# @return [XMLElement, OpenNebula::Error] the oned configuration in case
|
75
|
+
# of success, Error otherwise
|
76
|
+
def get_configuration()
|
77
|
+
rc = @client.call(SYSTEM_METHODS[:config])
|
78
|
+
|
79
|
+
if OpenNebula.is_error?(rc)
|
80
|
+
return rc
|
81
|
+
end
|
82
|
+
|
83
|
+
config = XMLElement.new
|
84
|
+
config.initialize_xml(rc, 'TEMPLATE')
|
85
|
+
|
86
|
+
return config
|
87
|
+
end
|
88
|
+
|
89
|
+
# Gets the default user quota limits
|
90
|
+
#
|
91
|
+
# @return [XMLElement, OpenNebula::Error] the default user quota in case
|
92
|
+
# of success, Error otherwise
|
93
|
+
def get_user_quotas()
|
94
|
+
rc = @client.call(SYSTEM_METHODS[:userquotainfo])
|
95
|
+
|
96
|
+
if OpenNebula.is_error?(rc)
|
97
|
+
return rc
|
98
|
+
end
|
99
|
+
|
100
|
+
default_quotas = XMLElement.new
|
101
|
+
default_quotas.initialize_xml(rc, 'DEFAULT_USER_QUOTAS')
|
102
|
+
|
103
|
+
return default_quotas
|
104
|
+
end
|
105
|
+
|
106
|
+
# Sets the default user quota limits
|
107
|
+
# @param quota [String] a template (XML or txt) with the new quota limits
|
108
|
+
#
|
109
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
110
|
+
# otherwise
|
111
|
+
def set_user_quotas(quota)
|
112
|
+
return @client.call(SYSTEM_METHODS[:userquotaupdate], quota)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Gets the default group quota limits
|
116
|
+
#
|
117
|
+
# @return [XMLElement, OpenNebula::Error] the default group quota in case
|
118
|
+
# of success, Error otherwise
|
119
|
+
def get_group_quotas()
|
120
|
+
rc = @client.call(SYSTEM_METHODS[:groupquotainfo])
|
121
|
+
|
122
|
+
if OpenNebula.is_error?(rc)
|
123
|
+
return rc
|
124
|
+
end
|
125
|
+
|
126
|
+
default_quotas = XMLElement.new
|
127
|
+
default_quotas.initialize_xml(rc, 'DEFAULT_GROUP_QUOTAS')
|
128
|
+
|
129
|
+
return default_quotas
|
130
|
+
end
|
131
|
+
|
132
|
+
# Sets the default group quota limits
|
133
|
+
# @param quota [String] a template (XML or txt) with the new quota limits
|
134
|
+
#
|
135
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
136
|
+
# otherwise
|
137
|
+
def set_group_quotas(quota)
|
138
|
+
return @client.call(SYSTEM_METHODS[:groupquotaupdate], quota)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -15,7 +15,7 @@
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'opennebula/pool_element'
|
19
19
|
|
20
20
|
module OpenNebula
|
21
21
|
class Template < PoolElement
|
@@ -32,7 +32,8 @@ module OpenNebula
|
|
32
32
|
:delete => "template.delete",
|
33
33
|
:chown => "template.chown",
|
34
34
|
:chmod => "template.chmod",
|
35
|
-
:clone => "template.clone"
|
35
|
+
:clone => "template.clone",
|
36
|
+
:rename => "template.rename"
|
36
37
|
}
|
37
38
|
|
38
39
|
# Creates a Template description with just its identifier
|
@@ -157,6 +158,16 @@ module OpenNebula
|
|
157
158
|
return rc
|
158
159
|
end
|
159
160
|
|
161
|
+
# Renames this Template
|
162
|
+
#
|
163
|
+
# @param name [String] New name for the Template.
|
164
|
+
#
|
165
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
166
|
+
# otherwise
|
167
|
+
def rename(name)
|
168
|
+
return call(TEMPLATE_METHODS[:rename], @pe_id, name)
|
169
|
+
end
|
170
|
+
|
160
171
|
#######################################################################
|
161
172
|
# Helpers to get Template information
|
162
173
|
#######################################################################
|
@@ -15,7 +15,7 @@
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'opennebula/pool_element'
|
19
19
|
|
20
20
|
module OpenNebula
|
21
21
|
class VirtualMachine < PoolElement
|
@@ -35,7 +35,8 @@ module OpenNebula
|
|
35
35
|
:chmod => "vm.chmod",
|
36
36
|
:monitoring => "vm.monitoring",
|
37
37
|
:attach => "vm.attach",
|
38
|
-
:detach => "vm.detach"
|
38
|
+
:detach => "vm.detach",
|
39
|
+
:rename => "vm.rename"
|
39
40
|
}
|
40
41
|
|
41
42
|
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
|
@@ -140,15 +141,16 @@ module OpenNebula
|
|
140
141
|
|
141
142
|
# Initiates the instance of the VM on the target host.
|
142
143
|
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
144
|
+
# @param host_id [Interger] The host id (hid) of the target host where
|
145
|
+
# the VM will be instantiated.
|
146
|
+
# @param enforce [true|false] If it is set to true, the host capacity
|
147
|
+
# will be checked, and the deployment will fail if the host is
|
148
|
+
# overcommited. Defaults to false
|
149
|
+
#
|
150
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
151
|
+
# otherwise
|
152
|
+
def deploy(host_id, enforce=false)
|
153
|
+
return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, enforce)
|
152
154
|
end
|
153
155
|
|
154
156
|
# Shutdowns an already deployed VM
|
@@ -247,23 +249,31 @@ module OpenNebula
|
|
247
249
|
end
|
248
250
|
|
249
251
|
# Saves a running VM and starts it again in the specified host
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
252
|
+
#
|
253
|
+
# @param host_id [Interger] The host id (hid) of the target host where
|
254
|
+
# the VM will be migrated.
|
255
|
+
# @param enforce [true|false] If it is set to true, the host capacity
|
256
|
+
# will be checked, and the deployment will fail if the host is
|
257
|
+
# overcommited. Defaults to false
|
258
|
+
#
|
259
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
260
|
+
# otherwise
|
261
|
+
def migrate(host_id, enforce=false)
|
262
|
+
return call(VM_METHODS[:migrate], @pe_id, host_id.to_i, false, enforce)
|
257
263
|
end
|
258
264
|
|
259
265
|
# Migrates a running VM to another host without downtime
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
266
|
+
#
|
267
|
+
# @param host_id [Interger] The host id (hid) of the target host where
|
268
|
+
# the VM will be migrated.
|
269
|
+
# @param enforce [true|false] If it is set to true, the host capacity
|
270
|
+
# will be checked, and the deployment will fail if the host is
|
271
|
+
# overcommited. Defaults to false
|
272
|
+
#
|
273
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
274
|
+
# otherwise
|
275
|
+
def live_migrate(host_id, enforce=false)
|
276
|
+
return call(VM_METHODS[:migrate], @pe_id, host_id.to_i, true, enforce)
|
267
277
|
end
|
268
278
|
|
269
279
|
# Set the specified vm's disk to be saved in a new image
|
@@ -352,6 +362,16 @@ module OpenNebula
|
|
352
362
|
return @client.call(VM_METHODS[:monitoring], @pe_id)
|
353
363
|
end
|
354
364
|
|
365
|
+
# Renames this VM
|
366
|
+
#
|
367
|
+
# @param name [String] New name for the VM.
|
368
|
+
#
|
369
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
370
|
+
# otherwise
|
371
|
+
def rename(name)
|
372
|
+
return call(VM_METHODS[:rename], @pe_id, name)
|
373
|
+
end
|
374
|
+
|
355
375
|
#######################################################################
|
356
376
|
# Helpers to get VirtualMachine information
|
357
377
|
#######################################################################
|
@@ -15,7 +15,7 @@
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'opennebula/pool_element'
|
19
19
|
|
20
20
|
module OpenNebula
|
21
21
|
class VirtualNetwork < PoolElement
|
@@ -34,7 +34,8 @@ module OpenNebula
|
|
34
34
|
:chmod => "vn.chmod",
|
35
35
|
:update => "vn.update",
|
36
36
|
:hold => "vn.hold",
|
37
|
-
:release => "vn.release"
|
37
|
+
:release => "vn.release",
|
38
|
+
:rename => "vn.rename"
|
38
39
|
}
|
39
40
|
|
40
41
|
VN_TYPES=%w{RANGED FIXED}
|
@@ -191,6 +192,16 @@ module OpenNebula
|
|
191
192
|
super(VN_METHODS[:chmod], owner_u, owner_m, owner_a, group_u,
|
192
193
|
group_m, group_a, other_u, other_m, other_a)
|
193
194
|
end
|
195
|
+
|
196
|
+
# Renames this virtual network
|
197
|
+
#
|
198
|
+
# @param name [String] New name for the virtual network.
|
199
|
+
#
|
200
|
+
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
201
|
+
# otherwise
|
202
|
+
def rename(name)
|
203
|
+
return call(VN_METHODS[:rename], @pe_id, name)
|
204
|
+
end
|
194
205
|
|
195
206
|
#######################################################################
|
196
207
|
# Helpers to get VirtualNetwork information
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
|
3
|
+
# #
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
5
|
+
# not use this file except in compliance with the License. You may obtain #
|
6
|
+
# a copy of the License at #
|
7
|
+
# #
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
9
|
+
# #
|
10
|
+
# Unless required by applicable law or agreed to in writing, software #
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
13
|
+
# See the License for the specific language governing permissions and #
|
14
|
+
# limitations under the License. #
|
15
|
+
#--------------------------------------------------------------------------- #
|
16
|
+
|
17
|
+
require 'openssl'
|
18
|
+
require 'base64'
|
19
|
+
require 'fileutils'
|
20
|
+
require 'yaml'
|
21
|
+
|
22
|
+
module OpenNebula; end
|
23
|
+
|
24
|
+
# X509 authentication class. It can be used as a driver for auth_mad
|
25
|
+
# as auth method is defined. It also holds some helper methods to be used
|
26
|
+
# by oneauth command
|
27
|
+
class OpenNebula::X509Auth
|
28
|
+
###########################################################################
|
29
|
+
#Constants with paths to relevant files and defaults
|
30
|
+
###########################################################################
|
31
|
+
if !ENV["ONE_LOCATION"]
|
32
|
+
ETC_LOCATION = "/etc/one"
|
33
|
+
else
|
34
|
+
ETC_LOCATION = ENV["ONE_LOCATION"] + "/etc"
|
35
|
+
end
|
36
|
+
|
37
|
+
LOGIN_PATH = ENV['HOME']+'/.one/one_x509'
|
38
|
+
|
39
|
+
X509_AUTH_CONF_PATH = ETC_LOCATION + "/auth/x509_auth.conf"
|
40
|
+
|
41
|
+
X509_DEFAULTS = {
|
42
|
+
:ca_dir => ETC_LOCATION + "/auth/certificates"
|
43
|
+
}
|
44
|
+
|
45
|
+
###########################################################################
|
46
|
+
# Initialize x509Auth object
|
47
|
+
#
|
48
|
+
# @param [Hash] default options for path
|
49
|
+
# @option options [String] :certs_pem
|
50
|
+
# cert chain array in colon-separated pem format
|
51
|
+
# @option options [String] :key_pem
|
52
|
+
# key in pem format
|
53
|
+
# @option options [String] :ca_dir
|
54
|
+
# directory of trusted CA's. Needed for auth method, not for login.
|
55
|
+
def initialize(options={})
|
56
|
+
@options ||= X509_DEFAULTS
|
57
|
+
@options.merge!(options)
|
58
|
+
|
59
|
+
load_options(X509_AUTH_CONF_PATH)
|
60
|
+
|
61
|
+
@cert_chain = @options[:certs_pem].collect do |cert_pem|
|
62
|
+
OpenSSL::X509::Certificate.new(cert_pem)
|
63
|
+
end
|
64
|
+
|
65
|
+
if @options[:key_pem]
|
66
|
+
@key = OpenSSL::PKey::RSA.new(@options[:key_pem])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
###########################################################################
|
71
|
+
# Client side
|
72
|
+
###########################################################################
|
73
|
+
|
74
|
+
# Creates the login file for x509 authentication at ~/.one/one_x509.
|
75
|
+
# By default it is valid as long as the certificate is valid. It can
|
76
|
+
# be changed to any number of seconds with expire parameter (sec.)
|
77
|
+
def login(user, expire=0)
|
78
|
+
write_login(login_token(user,expire))
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns a valid password string to create a user using this auth driver.
|
82
|
+
# In this case the dn of the user certificate.
|
83
|
+
def password
|
84
|
+
@cert_chain[0].subject.to_s.delete("\s")
|
85
|
+
end
|
86
|
+
|
87
|
+
# Generates a login token in the form:
|
88
|
+
# user_name:x509:user_name:time_expires:cert_chain
|
89
|
+
# - user_name:time_expires is encrypted with the user certificate
|
90
|
+
# - user_name:time_expires:cert_chain is base64 encoded
|
91
|
+
def login_token(user, expire)
|
92
|
+
if expire != 0
|
93
|
+
expires = Time.now.to_i + expire.to_i
|
94
|
+
else
|
95
|
+
expires = @cert_chain[0].not_after.to_i
|
96
|
+
end
|
97
|
+
|
98
|
+
text_to_sign = "#{user}:#{expires}"
|
99
|
+
signed_text = encrypt(text_to_sign)
|
100
|
+
|
101
|
+
certs_pem = @cert_chain.collect{|cert| cert.to_pem}.join(":")
|
102
|
+
|
103
|
+
token = "#{signed_text}:#{certs_pem}"
|
104
|
+
token64 = Base64::encode64(token).strip.delete("\n")
|
105
|
+
|
106
|
+
login_out = "#{user}:#{token64}"
|
107
|
+
|
108
|
+
login_out
|
109
|
+
end
|
110
|
+
|
111
|
+
###########################################################################
|
112
|
+
# Server side
|
113
|
+
###########################################################################
|
114
|
+
# auth method for auth_mad
|
115
|
+
def authenticate(user, pass, signed_text)
|
116
|
+
begin
|
117
|
+
# Decryption demonstrates that the user posessed the private key.
|
118
|
+
_user, expires = decrypt(signed_text).split(':')
|
119
|
+
|
120
|
+
return "User name missmatch" if user != _user
|
121
|
+
|
122
|
+
return "x509 proxy expired" if Time.now.to_i >= expires.to_i
|
123
|
+
|
124
|
+
# Some DN in the chain must match a DN in the password
|
125
|
+
dn_ok = @cert_chain.each do |cert|
|
126
|
+
if pass.split('|').include?(cert.subject.to_s.delete("\s"))
|
127
|
+
break true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
unless dn_ok == true
|
132
|
+
return "Certificate subject missmatch"
|
133
|
+
end
|
134
|
+
|
135
|
+
validate
|
136
|
+
|
137
|
+
return true
|
138
|
+
rescue => e
|
139
|
+
return e.message
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
# Writes a login_txt to the login file as defined in LOGIN_PATH
|
145
|
+
# constant
|
146
|
+
def write_login(login_txt)
|
147
|
+
# Inits login file path and creates ~/.one directory if needed
|
148
|
+
# Set instance variables
|
149
|
+
login_dir = File.dirname(LOGIN_PATH)
|
150
|
+
|
151
|
+
begin
|
152
|
+
FileUtils.mkdir_p(login_dir)
|
153
|
+
rescue Errno::EEXIST
|
154
|
+
end
|
155
|
+
|
156
|
+
file = File.open(LOGIN_PATH, "w")
|
157
|
+
file.write(login_txt)
|
158
|
+
file.close
|
159
|
+
|
160
|
+
File.chmod(0600,LOGIN_PATH)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Load class options form a configuration file (yaml syntax)
|
164
|
+
def load_options(conf_file)
|
165
|
+
if File.readable?(conf_file)
|
166
|
+
conf_txt = File.read(conf_file)
|
167
|
+
conf_opt = YAML::load(conf_txt)
|
168
|
+
|
169
|
+
@options.merge!(conf_opt) if conf_opt != false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
###########################################################################
|
174
|
+
# Methods to encrpyt/decrypt keys
|
175
|
+
###########################################################################
|
176
|
+
# Encrypts data with the private key of the user and returns
|
177
|
+
# base 64 encoded output in a single line
|
178
|
+
def encrypt(data)
|
179
|
+
return nil if !@key
|
180
|
+
Base64::encode64(@key.private_encrypt(data)).delete("\n").strip
|
181
|
+
end
|
182
|
+
|
183
|
+
# Decrypts base 64 encoded data with pub_key (public key)
|
184
|
+
def decrypt(data)
|
185
|
+
@cert_chain[0].public_key.public_decrypt(Base64::decode64(data))
|
186
|
+
end
|
187
|
+
|
188
|
+
###########################################################################
|
189
|
+
# Validate the user certificate
|
190
|
+
###########################################################################
|
191
|
+
def validate
|
192
|
+
now = Time.now
|
193
|
+
failed = "Could not validate user credentials: "
|
194
|
+
|
195
|
+
# Check start time and end time of certificates
|
196
|
+
@cert_chain.each do |cert|
|
197
|
+
if cert.not_before > now || cert.not_after < now
|
198
|
+
raise failed + "Certificate not valid. Current time is " +
|
199
|
+
now.localtime.to_s + "."
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
begin
|
204
|
+
# Validate the proxy certifcates
|
205
|
+
signee = @cert_chain[0]
|
206
|
+
|
207
|
+
@cert_chain[1..-1].each do |cert|
|
208
|
+
if !((signee.issuer.to_s == cert.subject.to_s) &&
|
209
|
+
(signee.verify(cert.public_key)))
|
210
|
+
raise failed + signee.subject.to_s + " with issuer " +
|
211
|
+
signee.issuer.to_s + " was not verified by " +
|
212
|
+
cert.subject.to_s + "."
|
213
|
+
end
|
214
|
+
signee = cert
|
215
|
+
end
|
216
|
+
|
217
|
+
# Validate the End Entity certificate
|
218
|
+
if !@options[:ca_dir]
|
219
|
+
raise failed + "No certifcate authority directory was specified."
|
220
|
+
end
|
221
|
+
|
222
|
+
begin
|
223
|
+
ca_hash = signee.issuer.hash.to_s(16)
|
224
|
+
ca_path = @options[:ca_dir] + '/' + ca_hash + '.0'
|
225
|
+
|
226
|
+
ca_cert = OpenSSL::X509::Certificate.new(File.read(ca_path))
|
227
|
+
|
228
|
+
if !((signee.issuer.to_s == ca_cert.subject.to_s) &&
|
229
|
+
(signee.verify(ca_cert.public_key)))
|
230
|
+
raise failed + signee.subject.to_s + " with issuer " +
|
231
|
+
signee.issuer.to_s + " was not verified by " +
|
232
|
+
ca_cert.subject.to_s + "."
|
233
|
+
end
|
234
|
+
|
235
|
+
signee = ca_cert
|
236
|
+
end while ca_cert.subject.to_s != ca_cert.issuer.to_s
|
237
|
+
rescue
|
238
|
+
raise
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -16,21 +16,6 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
module OpenNebula
|
19
|
-
|
20
|
-
begin
|
21
|
-
require 'nokogiri'
|
22
|
-
NOKOGIRI=true
|
23
|
-
rescue LoadError
|
24
|
-
NOKOGIRI=false
|
25
|
-
end
|
26
|
-
|
27
|
-
begin
|
28
|
-
require 'rexml/formatters/pretty'
|
29
|
-
REXML_FORMATTERS=true
|
30
|
-
rescue LoadError
|
31
|
-
REXML_FORMATTERS=false
|
32
|
-
end
|
33
|
-
|
34
19
|
# The XMLElement class provides an abstraction of the underlying
|
35
20
|
# XML parser engine. It provides XML-related methods for the Pool and
|
36
21
|
# PoolElement classes
|
@@ -79,12 +64,18 @@ module OpenNebula
|
|
79
64
|
|
80
65
|
return doc
|
81
66
|
end
|
82
|
-
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
67
|
+
|
68
|
+
# Extract a text element from the XML description of the PoolElement.
|
69
|
+
#
|
70
|
+
# @param [String] key Xpath expression
|
71
|
+
#
|
72
|
+
# @return [String, nil] If a text element is found, the element's
|
73
|
+
# text value. Otherwise, an empty string or nil, depending
|
74
|
+
# on the backend
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# vm['VID'] # gets VM id
|
78
|
+
# vm['HISTORY/HOSTNAME'] # get the hostname from the history
|
88
79
|
def [](key)
|
89
80
|
if NOKOGIRI
|
90
81
|
element=@xml.xpath(key.to_s)
|