Statistics
| Branch: | Tag: | Revision:

one / src / cloud / common / CloudClient.rb @ f93e2be0

History | View | Annotate | Download (6.79 KB)

1
# -------------------------------------------------------------------------- #
2
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                #
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 'rubygems'
18
require 'uri'
19

    
20
require 'digest/sha1'
21
require 'net/https'
22

    
23
require "rexml/document"
24

    
25
begin
26
    require 'rexml/formatters/pretty'
27
    REXML_FORMATTERS=true
28
rescue LoadError
29
    REXML_FORMATTERS=false
30
end
31

    
32
begin
33
    require 'curb'
34
    CURL_LOADED=true
35
rescue LoadError
36
    CURL_LOADED=false
37
end
38

    
39
begin
40
    require 'net/http/post/multipart'
41
    MULTIPART_LOADED=true
42
rescue LoadError
43
    MULTIPART_LOADED=false
44
end
45

    
46
###############################################################################
47
# The CloudClient module contains general functionality to implement a
48
# Cloud Client
49
###############################################################################
50
module CloudClient
51

    
52
    # OpenNebula version
53
    VERSION = '5.4.0'
54

    
55
    # #########################################################################
56
    # Default location for the authentication file
57
    # #########################################################################
58

    
59
    if ENV["HOME"]
60
        DEFAULT_AUTH_FILE = ENV["HOME"]+"/.one/one_auth"
61
    else
62
        DEFAULT_AUTH_FILE = "/var/lib/one/.one/one_auth"
63
    end
64

    
65
    # #########################################################################
66
    # Gets authorization credentials from ONE_AUTH or default
67
    # auth file.
68
    #
69
    # Raises an error if authorization is not found
70
    # #########################################################################
71

    
72
    def self.get_one_auth
73
        if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
74
            File.file?(ENV["ONE_AUTH"])
75
            one_auth=File.read(ENV["ONE_AUTH"]).strip.split(':')
76
        elsif File.file?(DEFAULT_AUTH_FILE)
77
            one_auth=File.read(DEFAULT_AUTH_FILE).strip.split(':')
78
        else
79
            raise "No authorization data present"
80
        end
81

    
82
        raise "Authorization data malformed" if one_auth.length < 2
83

    
84
        one_auth
85
    end
86

    
87
    # #########################################################################
88
    # Starts an http connection and calls the block provided. SSL flag
89
    # is set if needed.
90
    # #########################################################################
91
    def self.http_start(url, timeout, &block)
92
        host = nil
93
        port = nil
94

    
95
        if ENV['http_proxy']
96
            uri_proxy  = URI.parse(ENV['http_proxy'])
97
            host = uri_proxy.host
98
            port = uri_proxy.port
99
        end
100

    
101
        http = Net::HTTP::Proxy(host, port).new(url.host, url.port)
102

    
103
        if timeout
104
            http.read_timeout = timeout.to_i
105
        end
106

    
107
        if url.scheme=='https'
108
            http.use_ssl = true
109
            http.verify_mode=OpenSSL::SSL::VERIFY_NONE
110
        end
111

    
112
        begin
113
            res = http.start do |connection|
114
                block.call(connection)
115
            end
116
        rescue Errno::ECONNREFUSED => e
117
            str =  "Error connecting to server (#{e.to_s}).\n"
118
            str << "Server: #{url.host}:#{url.port}"
119

    
120
            return CloudClient::Error.new(str,"503")
121
        rescue Errno::ETIMEDOUT => e
122
            str =  "Error timeout connecting to server (#{e.to_s}).\n"
123
            str << "Server: #{url.host}:#{url.port}"
124

    
125
            return CloudClient::Error.new(str,"504")
126
        rescue Timeout::Error => e
127
            str =  "Error timeout while connected to server (#{e.to_s}).\n"
128
            str << "Server: #{url.host}:#{url.port}"
129

    
130
            return CloudClient::Error.new(str,"504")
131
        rescue SocketError => e
132
            str =  "Error timeout while connected to server (#{e.to_s}).\n"
133

    
134
            return CloudClient::Error.new(str,"503")
135
        rescue
136
            return CloudClient::Error.new($!.to_s,"503")
137
        end
138

    
139
        if res.is_a?(Net::HTTPSuccess)
140
            res
141
        else
142
            CloudClient::Error.new(res.body, res.code)
143
        end
144
    end
145

    
146
    # #########################################################################
147
    # The Error Class represents a generic error in the Cloud Client
148
    # library. It contains a readable representation of the error.
149
    # #########################################################################
150
    class Error
151
        attr_reader :message
152
        attr_reader :code
153

    
154
        # +message+ a description of the error
155
        def initialize(message=nil, code="500")
156
            @message=message
157
            @code=code
158
        end
159

    
160
        def to_s()
161
            @message
162
        end
163
    end
164

    
165
    # #########################################################################
166
    # Returns true if the object returned by a method of the OpenNebula
167
    # library is an Error
168
    # #########################################################################
169
    def self.is_error?(value)
170
        value.class==CloudClient::Error
171
    end
172
end
173

    
174
# Command line help functions
175
module CloudCLI
176
    def print_xml(xml_text)
177
        begin
178
            doc = REXML::Document.new(xml_text)
179
        rescue REXML::ParseException => e
180
            return e.message, -1
181
        end
182

    
183
        xml = doc.root
184

    
185
        if xml.nil?
186
            return xml_text, -1
187
        end
188

    
189
        str = String.new
190
        if REXML_FORMATTERS
191
            formatter = REXML::Formatters::Pretty.new
192
            formatter.compact = true
193

    
194
            formatter.write(xml,str)
195
        else
196
            str = xml.to_s
197
        end
198

    
199
        return str, 0
200
    end
201

    
202
    # Returns the command name
203
    def cmd_name
204
        File.basename($0)
205
    end
206

    
207
    def version_text
208
        version=<<EOT
209
OpenNebula #{CloudClient::VERSION}
210
Copyright 2002-2017, OpenNebula Project, OpenNebula Systems
211

212
Licensed under the Apache License, Version 2.0 (the "License"); you may
213
not use this file except in compliance with the License. You may obtain
214
a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
215
EOT
216
    end
217
end