opennebula-cli 3.8.0.beta1

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.
@@ -0,0 +1,256 @@
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 'cli_helper'
18
+
19
+ class OneQuotaHelper
20
+
21
+ EDITOR_PATH='/usr/bin/vi'
22
+
23
+ #---------------------------------------------------------------------------
24
+ # Tables to format user quotas
25
+ #---------------------------------------------------------------------------
26
+ TABLE_DS = CLIHelper::ShowTable.new(nil, self) do
27
+ column :"DATASTORE ID", "", :size=>12 do |d|
28
+ d["ID"] if !d.nil?
29
+ end
30
+
31
+ column :"IMAGES", "", :right, :size=>20 do |d|
32
+ "%8d / %8d" % [d["IMAGES_USED"], d["IMAGES"]] if !d.nil?
33
+ end
34
+
35
+ column :"SIZE", "", :right, :size=>19 do |d|
36
+ "%8s / %8s" % [OpenNebulaHelper.unit_to_str(d["SIZE_USED"].to_i,{},"M"),
37
+ OpenNebulaHelper.unit_to_str(d["SIZE"].to_i,{},"M")] if !d.nil?
38
+ end
39
+ end
40
+
41
+ TABLE_NET = CLIHelper::ShowTable.new(nil, self) do
42
+ column :"NETWORK ID", "", :size=>12 do |d|
43
+ d["ID"] if !d.nil?
44
+ end
45
+
46
+ column :"LEASES", "", :right, :size=>20 do |d|
47
+ "%8d / %8d" % [d["LEASES_USED"], d["LEASES"]] if !d.nil?
48
+ end
49
+ end
50
+
51
+ TABLE_VM = CLIHelper::ShowTable.new(nil, self) do
52
+
53
+ column :"NUMBER OF VMS", "", :right, :size=>20 do |d|
54
+ "%8d / %8d" % [d["VMS_USED"], d["VMS"]] if !d.nil?
55
+ end
56
+
57
+ column :"MEMORY", "", :right, :size=>20 do |d|
58
+ "%8s / %8s" % [OpenNebulaHelper.unit_to_str(d["MEMORY_USED"].to_i,{},"M"),
59
+ OpenNebulaHelper.unit_to_str(d["MEMORY"].to_i,{},"M")] if !d.nil?
60
+ end
61
+
62
+ column :"CPU", "", :right, :size=>20 do |d|
63
+ "%8.2f / %8.2f" % [d["CPU_USED"], d["CPU"]] if !d.nil?
64
+ end
65
+ end
66
+
67
+ TABLE_IMG = CLIHelper::ShowTable.new(nil, self) do
68
+ column :"IMAGE ID", "", :size=>12 do |d|
69
+ d["ID"] if !d.nil?
70
+ end
71
+
72
+ column :"RUNNING VMS", "", :right, :size=>20 do |d|
73
+ "%8d / %8d" % [d["RVMS_USED"], d["RVMS"]] if !d.nil?
74
+ end
75
+ end
76
+
77
+ HELP_QUOTA = <<-EOT.unindent
78
+ #-----------------------------------------------------------------------
79
+ # Supported quota limits:
80
+ #
81
+ # DATASTORE = [
82
+ # ID = <ID of the datastore>
83
+ # IMAGES = <Max. number of images in the datastore>
84
+ # SIZE = <Max. storage capacity (Mb) used in the datastore>
85
+ # ]
86
+ #
87
+ # VM = [
88
+ # VMS = <Max. number of VMs>
89
+ # MEMORY = <Max. allocated memory (Mb)>
90
+ # CPU = <Max. allocated CPU>
91
+ # ]
92
+ #
93
+ # NETWORK = [
94
+ # ID = <ID of the network>
95
+ # LEASES = <Max. number of IP leases from the network>
96
+ # ]
97
+ #
98
+ # IMAGE = [
99
+ # ID = <ID of the image>
100
+ # RVMS = <Max. number of VMs using the image>
101
+ # ]
102
+ #
103
+ # In any quota 0 means unlimited. The usage counters "*_USED" are
104
+ # shown for information purposes and will NOT be modified.
105
+ #-----------------------------------------------------------------------
106
+ EOT
107
+
108
+ # Edits the quota template of a resource
109
+ # @param resource [PoolElement] to get the current info from
110
+ # @param path [String] path to the new contents. If nil a editor will be
111
+ # used
112
+ # @return [String] contents of the new quotas
113
+ def self.set_quota(resource, path)
114
+ str = ""
115
+
116
+ if path.nil?
117
+ require 'tempfile'
118
+
119
+ tmp = Tempfile.new('one-cli')
120
+ path = tmp.path
121
+
122
+ rc = resource.info
123
+
124
+ if OpenNebula.is_error?(rc)
125
+ puts rc.message
126
+ exit -1
127
+ end
128
+
129
+ tmp << HELP_QUOTA
130
+ tmp << resource.template_like_str("DATASTORE_QUOTA") << "\n"
131
+ tmp << resource.template_like_str("VM_QUOTA") << "\n"
132
+ tmp << resource.template_like_str("NETWORK_QUOTA") << "\n"
133
+ tmp << resource.template_like_str("IMAGE_QUOTA") << "\n"
134
+
135
+ tmp.close
136
+
137
+ editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
138
+ system("#{editor_path} #{path}")
139
+
140
+ unless $?.exitstatus == 0
141
+ puts "Editor not defined"
142
+ exit -1
143
+ end
144
+
145
+ str = File.read(path)
146
+
147
+ File.unlink(path)
148
+ else
149
+ str = File.read(path)
150
+ end
151
+
152
+ str
153
+ end
154
+
155
+ # Retrieves a clean quota template, without any existing resource
156
+ # information
157
+ # @param path [String] path to the new contents. If nil a editor will be
158
+ # used
159
+ # @return [String] contents of the new quotas
160
+ def self.get_batch_quota(path)
161
+ str = ""
162
+
163
+ if path.nil?
164
+ require 'tempfile'
165
+
166
+ tmp = Tempfile.new('one-cli')
167
+ path = tmp.path
168
+
169
+ tmp << HELP_QUOTA << "\n"
170
+
171
+ tmp.close
172
+
173
+ editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
174
+ system("#{editor_path} #{path}")
175
+
176
+ unless $?.exitstatus == 0
177
+ puts "Editor not defined"
178
+ exit -1
179
+ end
180
+
181
+ str = File.read(path)
182
+
183
+ File.unlink(path)
184
+ else
185
+ str = File.read(path)
186
+ end
187
+
188
+ str
189
+ end
190
+
191
+ # Edits the quota template of a resource, adding the quotas set in str
192
+ # @param resource [PoolElement] to get the current info from
193
+ # @param str [String] quota template, created by get_batch_quota()
194
+ # @return [String, OpenNebula::Error] merged contents of the new quotas on
195
+ # success, Error if the user info could not be retrieved
196
+ def self.merge_quota(resource, str)
197
+ rc = resource.info
198
+
199
+ if OpenNebula.is_error?(rc)
200
+ return rc
201
+ end
202
+
203
+ # Instead of parsing the existing quotas, and deleting the ones that
204
+ # conflict with the batch quota string, the new quotas are placed at
205
+ # the end of the template sent to opennebula. This relies on the core
206
+ # reading them in order and replacing the quotas with each new
207
+ # appearance
208
+
209
+ tmp_str = ""
210
+
211
+ tmp_str << resource.template_like_str("DATASTORE_QUOTA") << "\n"
212
+ tmp_str << resource.template_like_str("VM_QUOTA") << "\n"
213
+ tmp_str << resource.template_like_str("NETWORK_QUOTA") << "\n"
214
+ tmp_str << resource.template_like_str("IMAGE_QUOTA") << "\n"
215
+
216
+ tmp_str << str
217
+
218
+ return tmp_str
219
+ end
220
+
221
+ # Outputs formated quota information to stdout
222
+ # @param qh [Hash] with the quotas for a given resource
223
+ #
224
+ def self.format_quota(qh)
225
+ str_h1="%-80s"
226
+
227
+ puts
228
+
229
+ CLIHelper.print_header(str_h1 % "RESOURCE USAGE & QUOTAS",false)
230
+
231
+ puts
232
+
233
+ vm_quotas = [qh['VM_QUOTA']['VM']].flatten
234
+ if !vm_quotas[0].nil?
235
+ TABLE_VM.show(vm_quotas, {})
236
+ puts
237
+ end
238
+
239
+ ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten
240
+ if !ds_quotas[0].nil?
241
+ TABLE_DS.show(ds_quotas, {})
242
+ puts
243
+ end
244
+
245
+ net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
246
+ if !net_quotas[0].nil?
247
+ TABLE_NET.show(net_quotas, {})
248
+ puts
249
+ end
250
+
251
+ image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
252
+ if !image_quotas[0].nil?
253
+ TABLE_IMG.show(image_quotas, {})
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,123 @@
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 'one_helper'
18
+
19
+ class OneTemplateHelper < OpenNebulaHelper::OneHelper
20
+ VM_NAME={
21
+ :name => "name",
22
+ :large => "--name name",
23
+ :format => String,
24
+ :description => <<-EOT.strip
25
+ Name of the new VM or TEMPLATE. When instantiating
26
+ multiple VMs you can use the\"%i\" wildcard to produce
27
+ different names such as vm-0, vm-1...
28
+ EOT
29
+ }
30
+
31
+ MULTIPLE={
32
+ :name => "multiple",
33
+ :short => "-m x",
34
+ :large => "--multiple x",
35
+ :format => Integer,
36
+ :description => "Instance multiple VMs"
37
+ }
38
+
39
+ def self.rname
40
+ "VMTEMPLATE"
41
+ end
42
+
43
+ def self.conf_file
44
+ "onetemplate.yaml"
45
+ end
46
+
47
+ def format_pool(options)
48
+ config_file = self.class.table_conf
49
+
50
+ table = CLIHelper::ShowTable.new(config_file, self) do
51
+ column :ID, "ONE identifier for the Template", :size=>4 do |d|
52
+ d["ID"]
53
+ end
54
+
55
+ column :NAME, "Name of the Template", :left, :size=>27 do |d|
56
+ d["NAME"]
57
+ end
58
+
59
+ column :USER, "Username of the Template owner", :left,
60
+ :size=>15 do |d|
61
+ helper.user_name(d, options)
62
+ end
63
+
64
+ column :GROUP, "Group of the Template", :left, :size=>15 do |d|
65
+ helper.group_name(d, options)
66
+ end
67
+
68
+ column :REGTIME, "Registration time of the Template",
69
+ :size=>15 do |d|
70
+ OpenNebulaHelper.time_to_str(d["REGTIME"])
71
+ end
72
+
73
+ default :ID, :USER, :GROUP, :NAME, :REGTIME
74
+ end
75
+
76
+ table
77
+ end
78
+
79
+ private
80
+
81
+ def factory(id=nil)
82
+ if id
83
+ OpenNebula::Template.new_with_id(id, @client)
84
+ else
85
+ xml=OpenNebula::Template.build_xml
86
+ OpenNebula::Template.new(xml, @client)
87
+ end
88
+ end
89
+
90
+ def factory_pool(user_flag=-2)
91
+ OpenNebula::TemplatePool.new(@client, user_flag)
92
+ end
93
+
94
+ def format_resource(template)
95
+ str="%-15s: %-20s"
96
+ str_h1="%-80s"
97
+
98
+ CLIHelper.print_header(
99
+ str_h1 % "TEMPLATE #{template['ID']} INFORMATION")
100
+ puts str % ["ID", template.id.to_s]
101
+ puts str % ["NAME", template.name]
102
+ puts str % ["USER", template['UNAME']]
103
+ puts str % ["GROUP", template['GNAME']]
104
+ puts str % ["REGISTER TIME",
105
+ OpenNebulaHelper.time_to_str(template['REGTIME'])]
106
+ puts
107
+
108
+ CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
109
+
110
+ ["OWNER", "GROUP", "OTHER"].each { |e|
111
+ mask = "---"
112
+ mask[0] = "u" if template["PERMISSIONS/#{e}_U"] == "1"
113
+ mask[1] = "m" if template["PERMISSIONS/#{e}_M"] == "1"
114
+ mask[2] = "a" if template["PERMISSIONS/#{e}_A"] == "1"
115
+
116
+ puts str % [e, mask]
117
+ }
118
+ puts
119
+
120
+ CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false)
121
+ puts template.template_str
122
+ end
123
+ end
@@ -0,0 +1,242 @@
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 'one_helper'
18
+ require 'one_helper/onequota_helper'
19
+
20
+ class OneUserHelper < OpenNebulaHelper::OneHelper
21
+ def self.rname
22
+ "USER"
23
+ end
24
+
25
+ def self.conf_file
26
+ "oneuser.yaml"
27
+ end
28
+
29
+ def self.password_to_str_desc
30
+ "User password"
31
+ end
32
+
33
+ def self.password_to_str(arg, options)
34
+ if options[:read_file]
35
+ begin
36
+ password = File.read(arg).split("\n").first
37
+ rescue
38
+ return -1, "Cannot read file: #{arg}"
39
+ end
40
+ else
41
+ password = arg.dup
42
+ end
43
+
44
+ if options[:driver] == OpenNebula::User::X509_AUTH
45
+ password.delete!("\s")
46
+ end
47
+
48
+ if options[:sha1] || options[:driver] == OpenNebula::User::CIPHER_AUTH
49
+ require 'digest/sha1'
50
+ password = Digest::SHA1.hexdigest(password)
51
+ end
52
+
53
+ return 0, password
54
+ end
55
+
56
+ def password(options)
57
+ case options[:driver]
58
+ when OpenNebula::User::SSH_AUTH
59
+ if !options[:key]
60
+ return -1, "You have to specify the --key option"
61
+ end
62
+
63
+ require 'ssh_auth'
64
+
65
+ begin
66
+ auth = SshAuth.new(:private_key=>options[:key])
67
+ rescue Exception => e
68
+ return -1, e.message
69
+ end
70
+ when OpenNebula::User::X509_AUTH
71
+ options[:cert] ||= ENV['X509_USER_CERT']
72
+
73
+ if !options[:cert]
74
+ return -1, "You have to specify the --cert option"
75
+ end
76
+
77
+ require 'x509_auth'
78
+
79
+ begin
80
+ cert = [File.read(options[:cert])]
81
+ auth = X509Auth.new(:certs_pem=>cert)
82
+ rescue Exception => e
83
+ return -1, e.message
84
+ end
85
+ else
86
+ return -1, "You have to specify an Auth method or define a password"
87
+ end
88
+
89
+ return 0, auth.password
90
+ end
91
+
92
+ def self.login(username, options)
93
+ case options[:driver]
94
+ when OpenNebula::User::SSH_AUTH
95
+ require 'ssh_auth'
96
+
97
+ options[:key] ||= ENV['HOME']+'/.ssh/id_rsa'
98
+
99
+ begin
100
+ auth = SshAuth.new(:private_key=>options[:key])
101
+ rescue Exception => e
102
+ return -1, e.message
103
+ end
104
+ when OpenNebula::User::X509_AUTH
105
+ require 'x509_auth'
106
+
107
+ options[:cert] ||= ENV['X509_USER_CERT']
108
+ options[:key] ||= ENV['X509_USER_KEY']
109
+
110
+ begin
111
+ certs = [File.read(options[:cert])]
112
+ key = File.read(options[:key])
113
+
114
+ auth = X509Auth.new(:certs_pem=>certs, :key_pem=>key)
115
+ rescue Exception => e
116
+ return -1, e.message
117
+ end
118
+ when OpenNebula::User::X509_PROXY_AUTH
119
+ require 'x509_auth'
120
+
121
+ options[:proxy] ||= ENV['X509_PROXY_CERT']
122
+
123
+ begin
124
+ proxy = File.read(options[:proxy])
125
+
126
+ certs = proxy.scan(/(-+BEGIN CERTIFICATE-+\n[^-]*\n-+END CERTIFICATE-+)/)
127
+ certs.flatten!
128
+
129
+ rc = proxy.match(/(-+BEGIN RSA PRIVATE KEY-+\n[^-]*\n-+END RSA PRIVATE KEY-+)/)
130
+ key= rc[1]
131
+
132
+ auth = X509Auth.new(:certs_pem=>certs, :key_pem=>key)
133
+ rescue => e
134
+ return -1, e.message
135
+ end
136
+ else
137
+ return -1, "You have to specify an Auth method"
138
+ end
139
+
140
+ options[:time] ||= 3600
141
+
142
+ auth.login(username, Time.now+options[:time])
143
+
144
+ return 0, 'export ONE_AUTH=' << auth.class::LOGIN_PATH
145
+ end
146
+
147
+ def format_pool(options)
148
+ config_file = self.class.table_conf
149
+
150
+ table = CLIHelper::ShowTable.new(config_file, self) do
151
+ column :ID, "ONE identifier for the User", :size=>4 do |d|
152
+ d["ID"]
153
+ end
154
+
155
+ column :NAME, "Name of the User", :left, :size=>15 do |d|
156
+ d["NAME"]
157
+ end
158
+
159
+ column :GROUP, "Group of the User", :left, :size=>10 do |d|
160
+ helper.group_name(d, options)
161
+ end
162
+
163
+ column :AUTH, "Auth driver of the User", :left, :size=>8 do |d|
164
+ d["AUTH_DRIVER"]
165
+ end
166
+
167
+ column :VMS , "Number of VMS", :size=>9 do |d|
168
+ if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
169
+ "%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], d['VM_QUOTA']['VM']["VMS"]]
170
+ else
171
+ "-"
172
+ end
173
+ end
174
+
175
+ column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
176
+ if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
177
+ d['VM_QUOTA']['VM']['MEMORY_USED']
178
+ "%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
179
+ OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY"].to_i,{},"M")]
180
+ else
181
+ "-"
182
+ end
183
+ end
184
+
185
+ column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
186
+ if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
187
+ "%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], d['VM_QUOTA']['VM']["CPU"]]
188
+ else
189
+ "-"
190
+ end
191
+ end
192
+
193
+ column :PASSWORD, "Password of the User", :size=>50 do |d|
194
+ d['PASSWORD']
195
+ end
196
+
197
+ default :ID, :NAME, :GROUP, :AUTH, :VMS, :MEMORY, :CPU
198
+ end
199
+
200
+ table
201
+ end
202
+
203
+ private
204
+
205
+ def factory(id=nil)
206
+ if id
207
+ OpenNebula::User.new_with_id(id, @client)
208
+ else
209
+ xml=OpenNebula::User.build_xml
210
+ OpenNebula::User.new(xml, @client)
211
+ end
212
+ end
213
+
214
+ def factory_pool(user_flag=-2)
215
+ #TBD OpenNebula::UserPool.new(@client, user_flag)
216
+ OpenNebula::UserPool.new(@client)
217
+ end
218
+
219
+ def format_resource(user)
220
+ str="%-15s: %-20s"
221
+ str_h1="%-80s"
222
+
223
+ CLIHelper.print_header(str_h1 % "USER #{user['ID']} INFORMATION")
224
+ puts str % ["ID", user.id.to_s]
225
+ puts str % ["NAME", user.name]
226
+ puts str % ["GROUP", user['GNAME']]
227
+ puts str % ["PASSWORD", user['PASSWORD']]
228
+ puts str % ["AUTH_DRIVER", user['AUTH_DRIVER']]
229
+
230
+ puts str % ["ENABLED",
231
+ OpenNebulaHelper.boolean_to_str(user['ENABLED'])]
232
+
233
+ puts
234
+
235
+ CLIHelper.print_header(str_h1 % "USER TEMPLATE",false)
236
+ puts user.template_str
237
+
238
+ user_hash = user.to_hash
239
+
240
+ OneQuotaHelper.format_quota(user_hash['USER'])
241
+ end
242
+ end