Revision a4715110

View differences:

src/sunstone/bin/sunstone-server
1
if [ -z "$ONE_LOCATION" ]; then
2
    SUNSTONE_PID=/var/run/one/sunstone.pid
3
    SUNSTONE_SERVER=/usr/lib/one/sunstone/config.ru
4
    SUNSTONE_LOCK_FILE=/var/lock/one/.sunstone.lock
5
    SUNSTONE_LOG=/var/log/one/sunstone.log
6
else
7
    SUNSTONE_PID=$ONE_LOCATION/var/sunstone.pid
8
    SUNSTONE_SERVER=$ONE_LOCATION/lib/sunstone/config.ru
9
    SUNSTONE_LOCK_FILE=$ONE_LOCATION/var/.sunstone.lock
10
    SUNSTONE_LOG=$ONE_LOCATION/var/sunstone.log
11
fi
12

  
13
PORT="4567"
14
HOST="127.0.0.1"
15

  
16
setup()
17
{
18

  
19
  if [ -f $SUNSTONE_LOCK_FILE ]; then
20
    if [ -f  $SUNSTONE_PID ]; then
21
      SUNSTONEPID=`cat $SUNSTONE_PID`
22
      ps $SUNSTONEPID &> /dev/null
23
      if [ $? -eq 0 ]; then
24
        echo "Sunstone Server is still running (PID:$SUNSTONEPID). Please try 'sunstone-server stop' first."
25
        exit 1
26
      fi
27
    fi
28
    echo "Stale .lock detected. Erasing it."
29
    rm $SUNSTONE_LOCK_FILE
30
  fi
31
}
32

  
33

  
34
start()
35
{
36
  if [ ! -f "$SUNSTONE_SERVER" ]; then
37
    echo "Can not find $SUNSTONE_SERVER."
38
    exit 1
39
  fi
40

  
41
  # Start the sunstone daemon
42
  touch $SUNSTONE_LOCK_FILE
43
  rackup $SUNSTONE_SERVER -s thin -p $PORT -o $HOST -P $SUNSTONE_PID &> $SUNSTONE_LOG &
44

  
45
  LASTRC=$?
46

  
47
  if [ $LASTRC -ne 0 ]; then
48
    echo "Error executing $SUNSTONE_SERVER"
49
    exit 1
50
  fi
51

  
52
  sleep 1
53
  ps $LASTPID &> /dev/null
54

  
55
  if [ $? -ne 0 ]; then
56
    echo "Error executing $SUNSTONE_SERVER."
57
    exit 1
58
  fi
59

  
60
  echo "sunstone-server started"
61
}
62

  
63
#
64
# Function that stops the daemon/service
65
#
66
stop()
67
{
68
  if [ ! -f $SUNSTONE_PID ]; then
69
    echo "Couldn't find sunstone-server process pid."
70
    exit 1
71
  fi
72

  
73
  # Kill the sunstone daemon
74
  kill -INT `cat $SUNSTONE_PID` &> /dev/null
75

  
76
  echo "sunstone-server stopped"
77
}
78

  
79
while getopts "p:h:" OPTION
80
do
81
  case $OPTION in
82
    p)  PORT=$OPTARG;;
83
    h)  HOST=$OPTARG;;
84
    \?) echo "Invalid option: -$OPTARG" >&2; exit 3 ;;
85
  esac
86
done
87

  
88
shift $((OPTIND-1))
89

  
90
case "$1" in
91
  start)
92
  setup
93
  start
94
  ;;
95
  stop)
96
  stop
97
  ;;
98
  *)
99
  echo "Usage: sunstone {start|stop}" >&2
100
  exit 3
101
  ;;
102
esac
src/sunstone/config.ru
19 19
# TBD Change path for intallation tree
20 20
$: << File.dirname(__FILE__)
21 21

  
22
require 'one-ui.rb'
22
require 'sunstone-server.rb'
23 23

  
24 24
run Sinatra::Application
src/sunstone/models/OneUI.rb
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
# TBD Change path for intallation tree
18

  
19
#require 'OpenNebulaJSON'
20
require 'models/OpenNebulaJSON'
21
include OpenNebulaJSON
22

  
23
class OneUI
24
    def initialize(username, password)
25
        # TBD one_client_user(name) from CloudServer
26
        @client = Client.new("dummy:dummy")
27
        @client.one_auth = "#{username}:#{password}"
28
    end
29

  
30
    ############################################################################
31
    #
32
    ############################################################################
33
    def self.authorize(user="", sha1_pass="")
34
        if user.empty? || sha1_pass.empty?
35
            return [401, false]
36
        end
37

  
38
        # TBD get_user_password(name) from CloudServer
39
        user_pool = UserPool.new(Client.new)
40
        rc = user_pool.info
41
        if OpenNebula.is_error?(rc)
42
            return [500, false]
43
        end
44

  
45
        user_pass = user_pool["USER[NAME=\"#{user}\"]/PASSWORD"]
46
        if user_pass == sha1_pass
47
            return [204, user_pool["USER[NAME=\"#{user}\"]/ID"]]
48
        else
49
            return [401, nil]
50
        end
51
    end
52

  
53
    ############################################################################
54
    #
55
    ############################################################################
56
    def get_pool(kind, user_id)
57
        user_flag = user_id=="0" ? -2 : -1
58

  
59
        pool = case kind
60
            when "cluster" then ClusterPoolJSON.new(@client)
61
            when "host"    then HostPoolJSON.new(@client)
62
            when "image"   then ImagePoolJSON.new(@client, user_flag)
63
            when "vm"      then VirtualMachinePoolJSON.new(@client, user_flag)
64
            when "vnet"    then VirtualNetworkPoolJSON.new(@client, user_flag)
65
            when "user"    then UserPoolJSON.new(@client)
66
            else
67
                error = Error.new("Error: #{kind} resource not supported")
68
                return [404, error.to_json]
69
        end
70

  
71
        rc = pool.info
72
        if OpenNebula.is_error?(rc)
73
            return [500, rc.to_json]
74
        else
75
            return [200, pool.to_json]
76
        end
77
    end
78

  
79
    ############################################################################
80
    #
81
    ############################################################################
82
    def get_resource(kind, id)
83
        resource = retrieve_resource(kind, id)
84
        if OpenNebula.is_error?(resource)
85
            return [404, resource.to_json]
86
        else
87
            return [200, resource.to_json]
88
        end
89
    end
90

  
91
    ############################################################################
92
    #
93
    ############################################################################
94
    def create_resource(kind, template)
95
        resource = case kind
96
            when "cluster" then ClusterJSON.new(Cluster.build_xml, @client)
97
            when "host"    then HostJSON.new(Host.build_xml, @client)
98
            when "image"   then ImageJSON.new(Image.build_xml, @client)
99
            when "vm"      then VirtualMachineJSON.new(VirtualMachine.build_xml,@client)
100
            when "vnet"    then VirtualNetworkJSON.new(VirtualNetwork.build_xml, @client)
101
            when "user"    then UserJSON.new(User.build_xml, @client)
102
            else
103
                error = Error.new("Error: #{kind} resource not supported")
104
                return [404, error.to_json]
105
        end
106

  
107
        rc = resource.allocate(template)
108
        if OpenNebula.is_error?(rc)
109
            return [500, rc.to_json]
110
        else
111
            resource.info
112
            return [201, resource.to_json]
113
        end
114
    end
115

  
116
    ############################################################################
117
    #
118
    ############################################################################
119
    def delete_resource(kind, id)
120
        resource = retrieve_resource(kind, id)
121
        if OpenNebula.is_error?(resource)
122
            return [404, resource.to_json]
123
        end
124

  
125
        rc = resource.delete
126
        if OpenNebula.is_error?(rc)
127
            return [500, rc.to_json]
128
        else
129
            return [204, resource.to_json]
130
        end
131
    end
132

  
133
    ############################################################################
134
    #
135
    ############################################################################
136
    def perform_action(kind, id, action_json)
137
        resource = retrieve_resource(kind, id)
138
        if OpenNebula.is_error?(resource)
139
            return [404, resource.to_json]
140
        end
141

  
142
        rc = resource.perform_action(action_json)
143
        if OpenNebula.is_error?(rc)
144
            return [500, rc.to_json]
145
        else
146
            return [204, resource.to_json]
147
        end
148
    end
149

  
150
    ############################################################################
151
    #
152
    ############################################################################
153
    def get_configuration
154
        one_config = VAR_LOCATION + "/config"
155
        config = Hash.new
156

  
157
        begin
158
            cfg = File.read(one_config)
159
        rescue Exception => e
160
            error = Error.new("Error reading config: #{e.inspect}")
161
            return [500, error.to_json]
162
        end
163

  
164
        cfg.lines do |line|
165
            m=line.match(/^([^=]+)=(.*)$/)
166

  
167
            if m
168
                name=m[1].strip.upcase
169
                value=m[2].strip
170
                config[name]=value
171
            end
172
        end
173

  
174
        return [200, config.to_json]
175
    end
176

  
177
    ############################################################################
178
    #
179
    ############################################################################
180
    def get_vm_log(id)
181
        id = id.to_s
182
        vm_log_file = VAR_LOCATION + "/#{id}/vm.log"
183

  
184
        begin
185
            log = File.read(vm_log_file)
186
        rescue Exception => e
187
            error = Error.new("Error: log for VM #{id} not available")
188
            return [500, error.to_s]
189
        end
190

  
191
        return [200, log]
192
    end
193

  
194
    private
195

  
196
    def retrieve_resource(kind, id)
197
        resource = case kind
198
            when "cluster" then ClusterJSON.new_with_id(id, @client)
199
            when "host"    then HostJSON.new_with_id(id, @client)
200
            when "image"   then ImageJSON.new_with_id(id, @client)
201
            when "vm"      then VirtualMachineJSON.new_with_id(id, @client)
202
            when "vnet"    then VirtualNetworkJSON.new_with_id(id, @client)
203
            when "user"    then UserJSON.new_with_id(id, @client)
204
            else
205
                error = Error.new("Error: #{kind} resource not supported")
206
                return error
207
        end
208

  
209
        rc = resource.info
210
        if OpenNebula.is_error?(rc)
211
            return rc
212
        else
213
            return resource
214
        end
215
    end
216
end
src/sunstone/models/OpenNebulaJSON.rb
18 18

  
19 19
if !ONE_LOCATION
20 20
    RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
21
    VAR_LOCATION      = "/var/lib/one"
22 21
else
23 22
    RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
24
    VAR_LOCATION      = ONE_LOCATION+"/var"
25 23
end
26 24

  
27 25
$: << RUBY_LIB_LOCATION
26
$: << File.dirname(__FILE__)
28 27

  
29 28
require 'OpenNebula'
30 29
include OpenNebula
31 30

  
32
# TBD Change path for intallation tree
33
#require 'OpenNebulaJSON/PoolJSON'
34
#require 'OpenNebulaJSON/HostJSON'
35
#require 'OpenNebulaJSON/JSONUtils'
36
require 'models/OpenNebulaJSON/ClusterJSON'
37
require 'models/OpenNebulaJSON/HostJSON'
38
require 'models/OpenNebulaJSON/ImageJSON'
39
require 'models/OpenNebulaJSON/JSONUtils'
40
require 'models/OpenNebulaJSON/PoolJSON'
41
require 'models/OpenNebulaJSON/UserJSON'
42
require 'models/OpenNebulaJSON/VirtualMachineJSON'
43
require 'models/OpenNebulaJSON/VirtualNetworkJSON'
31
require 'OpenNebulaJSON/ClusterJSON'
32
require 'OpenNebulaJSON/HostJSON'
33
require 'OpenNebulaJSON/ImageJSON'
34
require 'OpenNebulaJSON/JSONUtils'
35
require 'OpenNebulaJSON/PoolJSON'
36
require 'OpenNebulaJSON/UserJSON'
37
require 'OpenNebulaJSON/VirtualMachineJSON'
38
require 'OpenNebulaJSON/VirtualNetworkJSON'
44 39

  
45 40
module OpenNebula
46 41
    class Error
src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class ClusterJSON < OpenNebula::Cluster
src/sunstone/models/OpenNebulaJSON/HostJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class HostJSON < OpenNebula::Host
src/sunstone/models/OpenNebulaJSON/ImageJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class ImageJSON < OpenNebula::Image
src/sunstone/models/OpenNebulaJSON/PoolJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class HostPoolJSON < OpenNebula::HostPool; include JSONUtils; end
src/sunstone/models/OpenNebulaJSON/UserJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class UserJSON < OpenNebula::User
src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class VirtualMachineJSON < OpenNebula::VirtualMachine
src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'models/OpenNebulaJSON/JSONUtils'
17
require 'OpenNebulaJSON/JSONUtils'
18 18

  
19 19
module OpenNebulaJSON
20 20
    class VirtualNetworkJSON < OpenNebula::VirtualNetwork
src/sunstone/models/SunstoneServer.rb
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
# TBD Change path for intallation tree
18

  
19
#require 'OpenNebulaJSON'
20
require 'models/OpenNebulaJSON'
21
include OpenNebulaJSON
22

  
23
class OneUI
24
    def initialize(username, password)
25
        # TBD one_client_user(name) from CloudServer
26
        @client = Client.new("dummy:dummy")
27
        @client.one_auth = "#{username}:#{password}"
28
    end
29

  
30
    ############################################################################
31
    #
32
    ############################################################################
33
    def self.authorize(user="", sha1_pass="")
34
        if user.empty? || sha1_pass.empty?
35
            return [401, false]
36
        end
37

  
38
        # TBD get_user_password(name) from CloudServer
39
        user_pool = UserPool.new(Client.new)
40
        rc = user_pool.info
41
        if OpenNebula.is_error?(rc)
42
            return [500, false]
43
        end
44

  
45
        user_pass = user_pool["USER[NAME=\"#{user}\"]/PASSWORD"]
46
        if user_pass == sha1_pass
47
            return [204, user_pool["USER[NAME=\"#{user}\"]/ID"]]
48
        else
49
            return [401, nil]
50
        end
51
    end
52

  
53
    ############################################################################
54
    #
55
    ############################################################################
56
    def get_pool(kind, user_id)
57
        user_flag = user_id=="0" ? -2 : -1
58

  
59
        pool = case kind
60
            when "cluster" then ClusterPoolJSON.new(@client)
61
            when "host"    then HostPoolJSON.new(@client)
62
            when "image"   then ImagePoolJSON.new(@client, user_flag)
63
            when "vm"      then VirtualMachinePoolJSON.new(@client, user_flag)
64
            when "vnet"    then VirtualNetworkPoolJSON.new(@client, user_flag)
65
            when "user"    then UserPoolJSON.new(@client)
66
            else
67
                error = Error.new("Error: #{kind} resource not supported")
68
                return [404, error.to_json]
69
        end
70

  
71
        rc = pool.info
72
        if OpenNebula.is_error?(rc)
73
            return [500, rc.to_json]
74
        else
75
            return [200, pool.to_json]
76
        end
77
    end
78

  
79
    ############################################################################
80
    #
81
    ############################################################################
82
    def get_resource(kind, id)
83
        resource = retrieve_resource(kind, id)
84
        if OpenNebula.is_error?(resource)
85
            return [404, resource.to_json]
86
        else
87
            return [200, resource.to_json]
88
        end
89
    end
90

  
91
    ############################################################################
92
    #
93
    ############################################################################
94
    def create_resource(kind, template)
95
        resource = case kind
96
            when "cluster" then ClusterJSON.new(Cluster.build_xml, @client)
97
            when "host"    then HostJSON.new(Host.build_xml, @client)
98
            when "image"   then ImageJSON.new(Image.build_xml, @client)
99
            when "vm"      then VirtualMachineJSON.new(VirtualMachine.build_xml,@client)
100
            when "vnet"    then VirtualNetworkJSON.new(VirtualNetwork.build_xml, @client)
101
            when "user"    then UserJSON.new(User.build_xml, @client)
102
            else
103
                error = Error.new("Error: #{kind} resource not supported")
104
                return [404, error.to_json]
105
        end
106

  
107
        rc = resource.allocate(template)
108
        if OpenNebula.is_error?(rc)
109
            return [500, rc.to_json]
110
        else
111
            resource.info
112
            return [201, resource.to_json]
113
        end
114
    end
115

  
116
    ############################################################################
117
    #
118
    ############################################################################
119
    def delete_resource(kind, id)
120
        resource = retrieve_resource(kind, id)
121
        if OpenNebula.is_error?(resource)
122
            return [404, resource.to_json]
123
        end
124

  
125
        rc = resource.delete
126
        if OpenNebula.is_error?(rc)
127
            return [500, rc.to_json]
128
        else
129
            return [204, resource.to_json]
130
        end
131
    end
132

  
133
    ############################################################################
134
    #
135
    ############################################################################
136
    def perform_action(kind, id, action_json)
137
        resource = retrieve_resource(kind, id)
138
        if OpenNebula.is_error?(resource)
139
            return [404, resource.to_json]
140
        end
141

  
142
        rc = resource.perform_action(action_json)
143
        if OpenNebula.is_error?(rc)
144
            return [500, rc.to_json]
145
        else
146
            return [204, resource.to_json]
147
        end
148
    end
149

  
150
    ############################################################################
151
    #
152
    ############################################################################
153
    def get_configuration
154
        one_config = VAR_LOCATION + "/config"
155
        config = Hash.new
156

  
157
        begin
158
            cfg = File.read(one_config)
159
        rescue Exception => e
160
            error = Error.new("Error reading config: #{e.inspect}")
161
            return [500, error.to_json]
162
        end
163

  
164
        cfg.lines do |line|
165
            m=line.match(/^([^=]+)=(.*)$/)
166

  
167
            if m
168
                name=m[1].strip.upcase
169
                value=m[2].strip
170
                config[name]=value
171
            end
172
        end
173

  
174
        return [200, config.to_json]
175
    end
176

  
177
    ############################################################################
178
    #
179
    ############################################################################
180
    def get_vm_log(id)
181
        id = id.to_s
182
        vm_log_file = VAR_LOCATION + "/#{id}/vm.log"
183

  
184
        begin
185
            log = File.read(vm_log_file)
186
        rescue Exception => e
187
            error = Error.new("Error: log for VM #{id} not available")
188
            return [500, error.to_s]
189
        end
190

  
191
        return [200, log]
192
    end
193

  
194
    private
195

  
196
    def retrieve_resource(kind, id)
197
        resource = case kind
198
            when "cluster" then ClusterJSON.new_with_id(id, @client)
199
            when "host"    then HostJSON.new_with_id(id, @client)
200
            when "image"   then ImageJSON.new_with_id(id, @client)
201
            when "vm"      then VirtualMachineJSON.new_with_id(id, @client)
202
            when "vnet"    then VirtualNetworkJSON.new_with_id(id, @client)
203
            when "user"    then UserJSON.new_with_id(id, @client)
204
            else
205
                error = Error.new("Error: #{kind} resource not supported")
206
                return error
207
        end
208

  
209
        rc = resource.info
210
        if OpenNebula.is_error?(rc)
211
            return rc
212
        else
213
            return resource
214
        end
215
    end
216
end
src/sunstone/one-ui.rb
1
#!/usr/bin/env ruby
2

  
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

  
19
##############################################################################
20
# Environment Configuration for the Server
21
##############################################################################
22
HOST     = "127.0.0.1"
23
PORT     = "4567"
24

  
25

  
26
##############################################################################
27
# Required libraries
28
##############################################################################
29
require 'rubygems'
30
require 'sinatra'
31

  
32
require 'models/OneUI'
33

  
34

  
35
##############################################################################
36
# Sinatra Configuration
37
##############################################################################
38
set :host, HOST
39
set :port, PORT
40

  
41
use Rack::Session::Pool
42

  
43
##############################################################################
44
# Helpers
45
##############################################################################
46
helpers do
47
    def authorized?
48
        session["ip"] && session["ip"]==request.ip ? true : false
49
    end
50

  
51
    def build_session
52
        auth = Rack::Auth::Basic::Request.new(request.env)
53
        if auth.provided? && auth.basic? && auth.credentials
54
            user = auth.credentials[0]
55
            sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1])
56

  
57
            rc = OneUI.authorize(user, sha1_pass)
58
            if rc[1]
59
                session["user"]       = user
60
                session["user_id"]    = rc[1]
61
                session["password"]   = sha1_pass
62
                session["ip"]         = request.ip
63
                session["user_agent"] = request.user_agent
64
                session["remember"]   = params[:remember]
65

  
66
                if params[:remember]
67
                    env['rack.session.options'][:expire_after] = 30*60*60*24
68
                end
69

  
70
                return [204, ""]
71
            else
72
                return [rc.first, ""]
73
            end
74
        end
75

  
76
        return [401, ""]
77
    end
78

  
79
    def destroy_session
80
        session.clear
81
        return [204, ""]
82
    end
83
end
84

  
85
before do
86
    unless request.path=='/login' || request.path=='/'
87
        halt 401 unless authorized?
88

  
89
        @OneUI = OneUI.new(session["user"], session["password"])
90
    end
91
end
92

  
93
after do
94
    unless request.path=='/login' || request.path=='/'
95
        unless session['remember']
96
            if params[:timeout] === true
97
                env['rack.session.options'][:defer] = true
98
            else
99
                env['rack.session.options'][:expire_after] = 60*10
100
            end
101
        end
102
    end
103
end
104

  
105
##############################################################################
106
# HTML Requests
107
##############################################################################
108
get '/' do
109
    redirect '/login' unless authorized?
110
    time = Time.now + 60
111
    response.set_cookie("one-user", :value=>"#{session['user']}", :expires=>time)
112
    response.set_cookie("one-user_id", :value=>"#{session['user_id']}", :expires=>time)
113
    File.read(File.dirname(__FILE__)+'/templates/index.html')
114
end
115

  
116
get '/login' do
117
    File.read(File.dirname(__FILE__)+'/templates/login.html')
118
end
119

  
120
##############################################################################
121
# Login
122
##############################################################################
123
post '/login' do
124
    build_session
125
end
126

  
127
post '/logout' do
128
    destroy_session
129
end
130

  
131
##############################################################################
132
# GET Pool information
133
##############################################################################
134
get '/:pool' do
135
    @OneUI.get_pool(params[:pool], session["user_id"])
136
end
137

  
138
##############################################################################
139
# GET Resource information
140
##############################################################################
141
get '/:resource/:id' do
142
    @OneUI.get_resource(params[:resource], params[:id])
143
end
144

  
145
##############################################################################
146
# Delete Resource
147
##############################################################################
148
delete '/:resource/:id' do
149
    @OneUI.delete_resource(params[:resource], params[:id])
150
end
151

  
152
##############################################################################
153
# Create a new Resource
154
##############################################################################
155
post '/:pool' do
156
    @OneUI.create_resource(params[:pool], request.body.read)
157
end
158

  
159
##############################################################################
160
# Perform an action on a Resource
161
##############################################################################
162
post '/:resource/:id/action' do
163
    @OneUI.perform_action(params[:resource], params[:id], request.body.read)
164
end
165

  
166
##############################################################################
167
# Config and Logs
168
##############################################################################
169
get '/config' do
170
    @OneUI.get_configuration
171
end
172

  
173
get '/vm/:id/log' do
174
    @OneUI.get_vm_log(params[:id].to_i)
175
end
src/sunstone/sunstone-server.rb
1
#!/usr/bin/env ruby
2

  
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

  
19
##############################################################################
20
# Environment Configuration for the Server
21
##############################################################################
22
HOST     = "127.0.0.1"
23
PORT     = "4567"
24

  
25

  
26
##############################################################################
27
# Required libraries
28
##############################################################################
29
require 'rubygems'
30
require 'sinatra'
31

  
32
require 'models/OneUI'
33

  
34

  
35
##############################################################################
36
# Sinatra Configuration
37
##############################################################################
38
set :host, HOST
39
set :port, PORT
40

  
41
use Rack::Session::Pool
42

  
43
##############################################################################
44
# Helpers
45
##############################################################################
46
helpers do
47
    def authorized?
48
        session["ip"] && session["ip"]==request.ip ? true : false
49
    end
50

  
51
    def build_session
52
        auth = Rack::Auth::Basic::Request.new(request.env)
53
        if auth.provided? && auth.basic? && auth.credentials
54
            user = auth.credentials[0]
55
            sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1])
56

  
57
            rc = OneUI.authorize(user, sha1_pass)
58
            if rc[1]
59
                session["user"]       = user
60
                session["user_id"]    = rc[1]
61
                session["password"]   = sha1_pass
62
                session["ip"]         = request.ip
63
                session["user_agent"] = request.user_agent
64
                session["remember"]   = params[:remember]
65

  
66
                if params[:remember]
67
                    env['rack.session.options'][:expire_after] = 30*60*60*24
68
                end
69

  
70
                return [204, ""]
71
            else
72
                return [rc.first, ""]
73
            end
74
        end
75

  
76
        return [401, ""]
77
    end
78

  
79
    def destroy_session
80
        session.clear
81
        return [204, ""]
82
    end
83
end
84

  
85
before do
86
    unless request.path=='/login' || request.path=='/'
87
        halt 401 unless authorized?
88

  
89
        @OneUI = OneUI.new(session["user"], session["password"])
90
    end
91
end
92

  
93
after do
94
    unless request.path=='/login' || request.path=='/'
95
        unless session['remember']
96
            if params[:timeout] === true
97
                env['rack.session.options'][:defer] = true
98
            else
99
                env['rack.session.options'][:expire_after] = 60*10
100
            end
101
        end
102
    end
103
end
104

  
105
##############################################################################
106
# HTML Requests
107
##############################################################################
108
get '/' do
109
    redirect '/login' unless authorized?
110
    time = Time.now + 60
111
    response.set_cookie("one-user", :value=>"#{session['user']}", :expires=>time)
112
    response.set_cookie("one-user_id", :value=>"#{session['user_id']}", :expires=>time)
113
    File.read(File.dirname(__FILE__)+'/templates/index.html')
114
end
115

  
116
get '/login' do
117
    File.read(File.dirname(__FILE__)+'/templates/login.html')
118
end
119

  
120
##############################################################################
121
# Login
122
##############################################################################
123
post '/login' do
124
    build_session
125
end
126

  
127
post '/logout' do
128
    destroy_session
129
end
130

  
131
##############################################################################
132
# GET Pool information
133
##############################################################################
134
get '/:pool' do
135
    @OneUI.get_pool(params[:pool], session["user_id"])
136
end
137

  
138
##############################################################################
139
# GET Resource information
140
##############################################################################
141
get '/:resource/:id' do
142
    @OneUI.get_resource(params[:resource], params[:id])
143
end
144

  
145
##############################################################################
146
# Delete Resource
147
##############################################################################
148
delete '/:resource/:id' do
149
    @OneUI.delete_resource(params[:resource], params[:id])
150
end
151

  
152
##############################################################################
153
# Create a new Resource
154
##############################################################################
155
post '/:pool' do
156
    @OneUI.create_resource(params[:pool], request.body.read)
157
end
158

  
159
##############################################################################
160
# Perform an action on a Resource
161
##############################################################################
162
post '/:resource/:id/action' do
163
    @OneUI.perform_action(params[:resource], params[:id], request.body.read)
164
end
165

  
166
##############################################################################
167
# Config and Logs
168
##############################################################################
169
get '/config' do
170
    @OneUI.get_configuration
171
end
172

  
173
get '/vm/:id/log' do
174
    @OneUI.get_vm_log(params[:id].to_i)
175
end

Also available in: Unified diff