Statistics
| Branch: | Tag: | Revision:

one / src / cli / one_helper.rb @ 4edcd9ff

History | View | Annotate | Download (10.8 KB)

1
# -------------------------------------------------------------------------- #
2
# Copyright 2002-2011, 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
require 'OpenNebula'
20
include OpenNebula
21

    
22
module OpenNebulaHelper
23
    ONE_VERSION=<<-EOT
24
OpenNebula 2.3.0
25
Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
26

27
Licensed under the Apache License, Version 2.0 (the "License"); you may
28
not use this file except in compliance with the License. You may obtain
29
a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
30
EOT
31

    
32
    if ONE_LOCATION
33
        TABLE_CONF_PATH=ONE_LOCATION+"/etc/cli"
34
    else
35
        TABLE_CONF_PATH="/etc/one/cli"
36
    end
37

    
38
    EDITOR_PATH='/usr/bin/vi'
39

    
40
    ########################################################################
41
    # Options
42
    ########################################################################
43
    XML={
44
        :name  => "xml",
45
        :short => "-x",
46
        :large => "--xml",
47
        :description => "Show the resource in xml format"
48
    }
49

    
50
    NUMERIC={
51
        :name  => "numeric",
52
        :short => "-n",
53
        :large => "--numeric",
54
        :description => "Do not translate user and group IDs"
55
    }
56

    
57
    KILOBYTES={
58
        :name  => "kilobytes",
59
        :short => "-k",
60
        :large => "--kilobytes",
61
        :description => "Show units in kilobytes"
62
    }
63

    
64
    OPTIONS = XML, NUMERIC, KILOBYTES
65

    
66
    class OneHelper
67
        def initialize(secret=nil, endpoint=nil)
68
            @client = OpenNebula::Client.new(secret,endpoint)
69
            @translation_hash = nil
70
        end
71

    
72
        def create_resource(options, &block)
73
            resource = factory
74

    
75
            rc = block.call(resource)
76
            if OpenNebula.is_error?(rc)
77
                return -1, rc.message
78
            else
79
                puts "ID: #{resource.id.to_s}" if options[:verbose]
80
                return 0
81
            end
82
        end
83

    
84
        def list_pool(options, top=false)
85
            user_flag = options[:filter_flag] ? options[:filter_flag] : -2
86
            pool = factory_pool(user_flag)
87

    
88
            rc = pool.info
89
            return -1, rc.message if OpenNebula.is_error?(rc)
90

    
91
            if options[:xml]
92
                return 0, pool.to_xml(true)
93
            else
94
                phash = pool.to_hash
95
                rname = self.class.rname
96

    
97
                if phash["#{rname}_POOL"] && phash["#{rname}_POOL"]["#{rname}"]
98
                    if phash["#{rname}_POOL"]["#{rname}"].instance_of?(Array)
99
                        phash = phash["#{rname}_POOL"]["#{rname}"]
100
                    else
101
                        phash = [phash["#{rname}_POOL"]["#{rname}"]]
102
                    end
103
                else
104
                    phash = Array.new
105
                end
106

    
107
                format_pool(phash, options, top)
108
                return 0
109
            end
110
        end
111

    
112
        def show_resource(id, options)
113
            resource = retrieve_resource(id)
114
            return -1, resource.message if OpenNebula.is_error?(resource)
115

    
116
            if options[:xml]
117
                return 0, resource.to_xml(true)
118
            else
119
                format_resource(resource)
120
                return 0
121
            end
122
        end
123

    
124
        def perform_action(id, options, verbose, &block)
125
            resource = retrieve_resource(id)
126
            return -1, resource.message if OpenNebula.is_error?(resource)
127

    
128
            rc = block.call(resource)
129
            if OpenNebula.is_error?(rc)
130
                return -1, rc.message
131
            else
132
                puts "#{self.class.rname} #{id}: #{verbose}" if options[:verbose]
133
                return 0
134
            end
135
        end
136

    
137
        def perform_actions(ids,options,verbose,&block)
138
            exit_code = 0
139
            ids.each do |id|
140
                rc = perform_action(id,options,verbose,&block)
141

    
142
                unless rc[0]==0
143
                    puts rc[1]
144
                    exit_code=rc[0]
145
                end
146
            end
147

    
148
            exit_code
149
        end
150

    
151
        ########################################################################
152
        # Id translation
153
        ########################################################################
154
        def uid_to_str(uid, options={})
155
            rid_to_str(:users, uid, options)
156
        end
157

    
158
        def gid_to_str(gid, options={})
159
            rid_to_str(:groups, gid, options)
160
        end
161

    
162
        ########################################################################
163
        # Formatters for arguments
164
        ########################################################################
165
        def to_id(name)
166
            return 0, name if name.match(/^[0123456789]+$/)
167

    
168
            user_flag = -2
169
            pool = factory_pool(user_flag)
170
            poolname = self.class.rname
171

    
172
            self.class.id_to_name(name, pool, poolname)
173
        end
174

    
175
        def self.to_id_desc
176
            "OpenNebula #{self.rname} name or id"
177
        end
178

    
179
        def list_to_id(names)
180
            user_flag = -2
181
            pool = factory_pool(user_flag)
182

    
183
            rc = pool.info
184
            return -1, rc.message if OpenNebula.is_error?(rc)
185

    
186
            result = names.split(',').collect { |name|
187
                rc = to_id(name)
188
                unless rc.first==0
189
                    return rc
190
                end
191
                rc[1]
192
            }
193

    
194
            return 0, result
195
        end
196

    
197
        def self.list_to_id_desc
198
            "Comma-separated list of OpenNebula #{self.rname} names or ids"
199
        end
200

    
201
        def filterflag_to_i(str)
202
            filter_flag = case str
203
            when "a", "all" then "-2"
204
            when "m", "mine" then "-3"
205
            when "g", "group" then "-1"
206
            else
207
                if str.match(/^[0123456789]+$/)
208
                    str
209
                else
210
                    user = translation_hash[:users].select { |k,v| v==str }
211
                    user.length > 0 ? user.first.first : "-2"
212
                end
213
            end
214

    
215
            return 0, filter_flag
216
        end
217

    
218
        def self.filterflag_to_i_desc
219
            desc=<<-EOT
220
a, all       all the known #{self.rname}s
221
m, mine      the #{self.rname} belonging to the user in ONE_AUTH
222
g, group     'mine' plus the #{self.rname} belonging to the groups
223
             the user is member of
224
uid          #{self.rname} of the user identified by this uid
225
user         #{self.rname} of the user identified by the username
226
EOT
227
        end
228

    
229
        def self.table_conf
230
            path = "#{ENV["HOME"]}/.one/cli/#{self.conf_file}"
231

    
232
            if File.exists?(path)
233
                return path
234
            else
235
                return "#{TABLE_CONF_PATH}/#{self.conf_file}"
236
            end
237
        end
238

    
239
        def self.id_to_name(name, pool, ename)
240
            rc = pool.info
241
            return -1, rc.message if OpenNebula.is_error?(rc)
242

    
243
            objects=pool.select {|object| object.name==name }
244

    
245
            if objects.length>0
246
                if objects.length>1
247
                    return -1, "There are multiple #{ename}s with name #{name}."
248
                else
249
                    result = objects.first.id
250
                end
251
            else
252
                return -1,  "#{ename} named #{name} not found."
253
            end
254

    
255
            return 0, result
256
        end
257

    
258
        private
259

    
260
        def retrieve_resource(id)
261
            resource = factory(id)
262

    
263
            rc = resource.info
264
            OpenNebula.is_error?(rc) ? rc : resource
265
        end
266

    
267
        def translation_hash
268
            @translation_hash ||= {
269
                :users => generate_resource_translation(UserPool),
270
                :groups => generate_resource_translation(GroupPool)
271
            }
272
        end
273

    
274
        def generate_resource_translation(pool)
275
            p = pool.new(@client)
276
            p.info
277

    
278
            hash = Hash.new
279
            p.each { |r| hash[r["ID"]]=r["NAME"] }
280
            hash
281
        end
282

    
283
        def rid_to_str(resource, id, options)
284
            if options[:numeric]
285
                id
286
            else
287
                if name = translation_hash[resource][id]
288
                    name
289
                else
290
                    id
291
                end
292
            end
293
        end
294
    end
295

    
296
    def OpenNebulaHelper.name_to_id(name, poolname, user_flag=-2)
297
        return 0, name.to_i if name.match(/^[0123456789]+$/)
298

    
299
        client = OpenNebula::Client.new
300
        # TBD user_flag
301
        pool = case poolname
302
        when "HOST"  then  OpenNebula::HostPool.new(client)
303
        when "GROUP" then OpenNebula::GroupPool.new(client)
304
        when "USER"  then OpenNebula::UserPool.new(client)
305
        end
306

    
307
        OneHelper.id_to_name(name, pool, poolname)
308
    end
309

    
310
    def OpenNebulaHelper.name_to_id_desc(poolname)
311
        "OpenNebula #{poolname} name or id"
312
    end
313
    def OpenNebulaHelper.public_to_str(str)
314
        if str.to_i == 1
315
            public_str = "Y"
316
        else
317
            public_str = "N"
318
        end
319
    end
320

    
321
    def OpenNebulaHelper.time_to_str(time)
322
        value=time.to_i
323
        if value==0
324
            value='-'
325
        else
326
            value=Time.at(value).strftime("%m/%d %H:%M:%S")
327
        end
328
    end
329

    
330
    BinarySufix = ["K", "M", "G", "T" ]
331

    
332
    def OpenNebulaHelper.unit_to_str(value, options)
333
        if options[:kilobytes]
334
            value
335
        else
336
            i=0
337

    
338
            while value > 1024 && i < 3 do
339
                value /= 1024.0
340
                i+=1
341
            end
342

    
343
            value = (value * 10).round / 10.0
344

    
345
            value = value.to_i if value - value.round == 0
346
            st = value.to_s + BinarySufix[i]
347
        end
348
    end
349

    
350
    def OpenNebulaHelper.update_template(id, resource)
351
        require 'tempfile'
352

    
353
        tmp  = Tempfile.new(id)
354
        path = tmp.path
355

    
356
        tmp << resource.template_str
357
        tmp.flush
358

    
359
        editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
360
        system("#{editor_path} #{path}")
361
        unless $?==0
362
            puts "Editor not defined"
363
            exit -1
364
        end
365

    
366
        tmp.close
367

    
368
        str = File.read(path)
369
        str
370
    end
371
end