opennebula 3.9.80.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.
Files changed (42) hide show
  1. data/LICENSE +202 -0
  2. data/NOTICE +47 -0
  3. data/lib/opennebula.rb +58 -0
  4. data/lib/opennebula/acl.rb +266 -0
  5. data/lib/opennebula/acl_pool.rb +55 -0
  6. data/lib/opennebula/client.rb +119 -0
  7. data/lib/opennebula/cluster.rb +249 -0
  8. data/lib/opennebula/cluster_pool.rb +58 -0
  9. data/lib/opennebula/datastore.rb +171 -0
  10. data/lib/opennebula/datastore_pool.rb +55 -0
  11. data/lib/opennebula/document.rb +261 -0
  12. data/lib/opennebula/document_json.rb +131 -0
  13. data/lib/opennebula/document_pool.rb +102 -0
  14. data/lib/opennebula/document_pool_json.rb +58 -0
  15. data/lib/opennebula/error.rb +52 -0
  16. data/lib/opennebula/group.rb +163 -0
  17. data/lib/opennebula/group_pool.rb +56 -0
  18. data/lib/opennebula/host.rb +201 -0
  19. data/lib/opennebula/host_pool.rb +93 -0
  20. data/lib/opennebula/image.rb +297 -0
  21. data/lib/opennebula/image_pool.rb +79 -0
  22. data/lib/opennebula/ldap_auth.rb +99 -0
  23. data/lib/opennebula/ldap_auth_spec.rb +70 -0
  24. data/lib/opennebula/pool.rb +160 -0
  25. data/lib/opennebula/pool_element.rb +269 -0
  26. data/lib/opennebula/server_cipher_auth.rb +148 -0
  27. data/lib/opennebula/server_x509_auth.rb +104 -0
  28. data/lib/opennebula/ssh_auth.rb +139 -0
  29. data/lib/opennebula/system.rb +141 -0
  30. data/lib/opennebula/template.rb +213 -0
  31. data/lib/opennebula/template_pool.rb +79 -0
  32. data/lib/opennebula/user.rb +174 -0
  33. data/lib/opennebula/user_pool.rb +55 -0
  34. data/lib/opennebula/virtual_machine.rb +560 -0
  35. data/lib/opennebula/virtual_machine_pool.rb +323 -0
  36. data/lib/opennebula/virtual_network.rb +249 -0
  37. data/lib/opennebula/virtual_network_pool.rb +79 -0
  38. data/lib/opennebula/x509_auth.rb +288 -0
  39. data/lib/opennebula/xml_element.rb +427 -0
  40. data/lib/opennebula/xml_pool.rb +45 -0
  41. data/lib/opennebula/xml_utils.rb +34 -0
  42. metadata +118 -0
@@ -0,0 +1,148 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
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 'digest/sha1'
19
+
20
+ require 'base64'
21
+ require 'fileutils'
22
+
23
+ module OpenNebula; end
24
+
25
+ # Server authentication class. This method can be used by OpenNebula services
26
+ # to let access authenticated users by other means. It is based on OpenSSL
27
+ # symmetric ciphers
28
+ class OpenNebula::ServerCipherAuth
29
+ ###########################################################################
30
+ #Constants with paths to relevant files and defaults
31
+ ###########################################################################
32
+
33
+ CIPHER = "aes-256-cbc"
34
+
35
+ ###########################################################################
36
+
37
+ def initialize(srv_user, srv_passwd)
38
+ @srv_user = srv_user
39
+ @srv_passwd = srv_passwd
40
+
41
+ if !srv_passwd.empty?
42
+ @key = Digest::SHA1.hexdigest(@srv_passwd)
43
+ else
44
+ @key = ""
45
+ end
46
+
47
+ @cipher = OpenSSL::Cipher::Cipher.new(CIPHER)
48
+ end
49
+
50
+ ###########################################################################
51
+ # Client side
52
+ ###########################################################################
53
+
54
+ # Creates a ServerCipher for client usage
55
+ def self.new_client(srv_user=nil, srv_passwd=nil)
56
+ if ( srv_user == nil || srv_passwd == nil )
57
+ begin
58
+ if ENV["ONE_CIPHER_AUTH"] and !ENV["ONE_CIPHER_AUTH"].empty?
59
+ one_auth = File.read(ENV["ONE_CIPHER_AUTH"])
60
+ else
61
+ raise "ONE_CIPHER_AUTH environment variable not set"
62
+ end
63
+
64
+ one_auth.rstrip!
65
+
66
+ rc = one_auth.match(/(.*?):(.*)/)
67
+
68
+ if rc.nil?
69
+ raise "Bad format for one_auth token (<user>:<passwd>)"
70
+ else
71
+ srv_user = rc[1]
72
+ srv_passwd = rc[2]
73
+ end
74
+ rescue => e
75
+ raise e.message
76
+ end
77
+ end
78
+
79
+ self.new(srv_user, srv_passwd)
80
+ end
81
+
82
+ # Generates a login token in the form:
83
+ # - server_user:target_user:time_expires
84
+ # The token is then encrypted with the contents of one_auth
85
+ def login_token(expire, target_user=nil)
86
+ target_user ||= @srv_user
87
+ token_txt = "#{@srv_user}:#{target_user}:#{expire}"
88
+
89
+ token = encrypt(token_txt)
90
+ token64 = Base64::encode64(token).strip.delete("\n")
91
+
92
+ return "#{@srv_user}:#{target_user}:#{token64}"
93
+ end
94
+
95
+ # Returns a valid password string to create a user using this auth driver
96
+ def password
97
+ return @srv_passwd
98
+ end
99
+
100
+ ###########################################################################
101
+ # Driver side
102
+ ###########################################################################
103
+
104
+ # Creates a ServerCipher for driver usage
105
+ def self.new_driver()
106
+ self.new("","")
107
+ end
108
+
109
+ # auth method for auth_mad
110
+ def authenticate(srv_user,srv_pass, signed_text)
111
+ begin
112
+ @key = srv_pass
113
+
114
+ s_user, t_user, expires = decrypt(signed_text).split(':')
115
+
116
+ return "User name missmatch" if s_user != srv_user
117
+
118
+ return "login token expired" if Time.now.to_i >= expires.to_i
119
+
120
+ return true
121
+ rescue => e
122
+ return e.message
123
+ end
124
+ end
125
+
126
+ private
127
+
128
+ def encrypt(data)
129
+ @cipher.encrypt
130
+ @cipher.key = @key
131
+
132
+ rc = @cipher.update(data)
133
+ rc << @cipher.final
134
+
135
+ return rc
136
+ end
137
+
138
+ def decrypt(data)
139
+ @cipher.decrypt
140
+ @cipher.key = @key
141
+
142
+ rc = @cipher.update(Base64::decode64(data))
143
+ rc << @cipher.final
144
+
145
+ return rc
146
+ end
147
+ end
148
+
@@ -0,0 +1,104 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
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
+
21
+ require 'opennebula/x509_auth'
22
+
23
+ module OpenNebula; end
24
+
25
+ # Server authentication class. This authmethod can be used by opennebula services
26
+ # to let access authenticated users by other means. It is based on x509 server
27
+ # certificates
28
+ class OpenNebula::ServerX509Auth < OpenNebula::X509Auth
29
+ ###########################################################################
30
+ #Constants with paths to relevant files and defaults
31
+ ###########################################################################
32
+
33
+ SERVER_AUTH_CONF_PATH = ETC_LOCATION + "/auth/server_x509_auth.conf"
34
+
35
+ SERVER_DEFAULTS = {
36
+ :one_cert => ETC_LOCATION + "/auth/cert.pem",
37
+ :one_key => ETC_LOCATION + "/auth/key.pem"
38
+ }
39
+
40
+ ###########################################################################
41
+
42
+ def initialize()
43
+ @options = SERVER_DEFAULTS
44
+
45
+ load_options(SERVER_AUTH_CONF_PATH)
46
+
47
+ begin
48
+ certs = [ File.read(@options[:one_cert]) ]
49
+ key = File.read(@options[:one_key])
50
+
51
+ super(:certs_pem => certs, :key_pem => key)
52
+ rescue
53
+ raise
54
+ end
55
+
56
+ if @options[:srv_user] == nil || @options[:srv_user].empty?
57
+ raise "User for x509 server not defined"
58
+ end
59
+ end
60
+
61
+ ###########################################################################
62
+ # Client side
63
+ ###########################################################################
64
+
65
+ # Creates a ServerCipher for client and driver sage
66
+ class << OpenNebula::ServerX509Auth
67
+ alias :new_client :new
68
+ alias :new_driver :new
69
+ end
70
+
71
+ # Generates a login token in the form:
72
+ # - server_user:target_user:time_expires
73
+ def login_token(expire, target_user=nil)
74
+ target_user ||= @options[:srv_user]
75
+ token_txt = "#{@options[:srv_user]}:#{target_user}:#{expire}"
76
+
77
+ token = encrypt(token_txt)
78
+ token64 = Base64::encode64(token).strip.delete("\n")
79
+
80
+ return "#{@options[:srv_user]}:#{target_user}:#{token64}"
81
+ end
82
+
83
+ ###########################################################################
84
+ # Server side
85
+ ###########################################################################
86
+
87
+ # auth method for auth_mad
88
+ def authenticate(server_user, server_pass, signed_text)
89
+ begin
90
+ s_user, t_user, expires = decrypt(signed_text).split(':')
91
+
92
+ return "Server password missmatch" if server_pass != password
93
+
94
+ return "User name missmatch" if ( s_user != server_user ||
95
+ s_user != @options[:srv_user] )
96
+
97
+ return "login token expired" if Time.now.to_i >= expires.to_i
98
+
99
+ return true
100
+ rescue => e
101
+ return e.message
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,139 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
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 'pp'
19
+ require 'openssl'
20
+ require 'base64'
21
+ require 'fileutils'
22
+
23
+ module OpenNebula; end
24
+
25
+ # SSH key authentication class. It can be used as a driver for auth_mad
26
+ # as auth method is defined. It also holds some helper methods to be used
27
+ # by oneauth command
28
+ class OpenNebula::SshAuth
29
+ LOGIN_PATH = ENV['HOME']+'/.one/one_ssh'
30
+
31
+ # Initialize SshAuth object
32
+ #
33
+ # @param [Hash] default options for path
34
+ # @option options [String] :public_key public key for the user
35
+ # @option options [String] :private_key key private key for the user.
36
+ def initialize(options={})
37
+ @private_key = nil
38
+ @public_key = nil
39
+
40
+ if options[:private_key]
41
+ begin
42
+ @private_key = File.read(options[:private_key])
43
+ rescue Exception => e
44
+ raise "Cannot read #{options[:private_key]}"
45
+ end
46
+ end
47
+
48
+ if options[:public_key]
49
+ @public_key = options[:public_key]
50
+ elsif @private_key != nil
51
+ # Init ssh keys using private key. public key is extracted in a
52
+ # format compatible with openssl. The public key does not contain
53
+ # "---- BEGIN/END RSA PUBLIC KEY ----" and is in a single line
54
+ key = OpenSSL::PKey::RSA.new(@private_key)
55
+
56
+ @public_key = key.public_key.to_pem.split("\n")
57
+ @public_key = @public_key.reject {|l| l.match(/RSA PUBLIC KEY/) }.join('')
58
+ end
59
+
60
+ if @private_key.nil? && @public_key.nil?
61
+ raise "You have to define at least one of the keys"
62
+ end
63
+ end
64
+
65
+ # Creates the login file for ssh authentication at ~/.one/one_ssh.
66
+ # By default it is valid for 1 hour but it can be changed to any number
67
+ # of seconds with expire parameter (in seconds)
68
+ def login(user, expire=3600)
69
+ expire ||= 3600
70
+
71
+ # Init proxy file path and creates ~/.one directory if needed
72
+ proxy_dir = File.dirname(LOGIN_PATH)
73
+
74
+ begin
75
+ FileUtils.mkdir_p(proxy_dir)
76
+ rescue Errno::EEXIST
77
+ end
78
+
79
+ # Generate security token
80
+ time = Time.now.to_i + expire.to_i
81
+
82
+ secret_plain = "#{user}:#{time}"
83
+ secret_crypted = encrypt(secret_plain)
84
+
85
+ proxy = "#{user}:#{secret_crypted}"
86
+
87
+ file = File.open(LOGIN_PATH, "w")
88
+ file.write(proxy)
89
+ file.close
90
+
91
+ File.chmod(0600,LOGIN_PATH)
92
+
93
+ secret_crypted
94
+ end
95
+
96
+ # Returns a valid password string to create a user using this auth driver.
97
+ # In this case the ssh public key.
98
+ def password
99
+ @public_key
100
+ end
101
+
102
+ # Checks the proxy created with the login method
103
+ def authenticate(user, token)
104
+ begin
105
+ token_plain = decrypt(token)
106
+ _user, time = token_plain.split(':')
107
+
108
+ if user == _user
109
+ if Time.now.to_i >= time.to_i
110
+ return "ssh proxy expired, login again to renew it"
111
+ else
112
+ return true
113
+ end
114
+ else
115
+ return "invalid credentials"
116
+ end
117
+ rescue
118
+ return "error"
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ ###########################################################################
125
+ # Methods to handle ssh keys
126
+ ###########################################################################
127
+ # Encrypts data with the private key of the user and returns
128
+ # base 64 encoded output in a single line
129
+ def encrypt(data)
130
+ rsa=OpenSSL::PKey::RSA.new(@private_key)
131
+ Base64::encode64(rsa.private_encrypt(data)).gsub!(/\n/, '').strip
132
+ end
133
+
134
+ # Decrypts base 64 encoded data with pub_key (public key)
135
+ def decrypt(data)
136
+ rsa=OpenSSL::PKey::RSA.new(Base64::decode64(@public_key))
137
+ rsa.public_decrypt(Base64::decode64(data))
138
+ end
139
+ end
@@ -0,0 +1,141 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
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