~ubuntu-cloud-archive/ubuntu/precise/nova/trunk

« back to all changes in this revision

Viewing changes to bin/nova-novncproxy

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-07-06 10:18:33 UTC
  • mfrom: (1.1.58)
  • Revision ID: package-import@ubuntu.com-20120706101833-wp2nv392mpe9re8p
Tags: 2012.2~f2-0ubuntu1
[ Adam Gandelman ]
* Use new rootwrap configuration structure:
  - debian/nova-{compute, network, volume}.{pyinstall, pyremove}: Dropped.
  - debian/nova-common.dirs: Add /etc/nova/rootwrap.d/.
  - debian/nova-common.install: Install /etc/nova/rootwrap.conf.
  - debian/debian/nova.conf: Reference rootwrap.conf in calls to
    nova-rootwrap.
  - debian/nova-{compute, network, volume}.install: Install corresponding
    filter in /etc/nova/rootwrap.d/
* debian/rules: Install logging_sample.conf to /etc/nova/logging.conf
  as part of nova-common.
* debian/pydist-overrides: Add setuptools-git.
* debian/control: Add python-setuptools-git as a Build-Depends.
* debian/rules: Do not remove nova.egg-info during auto_clean.  Now that
  upstream has moved to setuptools-git, doing so results in missing files
  from built package.

[ Chuck Short ]
* New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
3
 
 
4
# Copyright (c) 2012 Openstack, LLC.
 
5
# All Rights Reserved.
 
6
#
 
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
8
#    not use this file except in compliance with the License. You may obtain
 
9
#    a copy of the License at
 
10
#
 
11
#         http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
#    Unless required by applicable law or agreed to in writing, software
 
14
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
15
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
16
#    License for the specific language governing permissions and limitations
 
17
#    under the License.
 
18
 
 
19
'''
 
20
Websocket proxy that is compatible with Openstack Nova.
 
21
Leverages websockify.py by Joel Martin
 
22
'''
 
23
 
 
24
import Cookie
 
25
import os
 
26
import socket
 
27
import sys
 
28
 
 
29
import websockify
 
30
 
 
31
from nova import context
 
32
from nova import flags
 
33
from nova.openstack.common import cfg
 
34
from nova.openstack.common import log as logging
 
35
from nova import rpc
 
36
from nova import utils
 
37
 
 
38
 
 
39
opts = [
 
40
    cfg.BoolOpt('record',
 
41
                default=False,
 
42
                help='Record sessions to FILE.[session_number]'),
 
43
    cfg.BoolOpt('daemon',
 
44
                default=False,
 
45
                help='Become a daemon (background process)'),
 
46
    cfg.BoolOpt('ssl_only',
 
47
                default=False,
 
48
                help='Disallow non-encrypted connections'),
 
49
    cfg.BoolOpt('source_is_ipv6',
 
50
                default=False,
 
51
                help='Source is ipv6'),
 
52
    cfg.StrOpt('cert',
 
53
               default='self.pem',
 
54
               help='SSL certificate file'),
 
55
    cfg.StrOpt('key',
 
56
               default=None,
 
57
               help='SSL key file (if separate from cert)'),
 
58
    cfg.StrOpt('web',
 
59
               default='/usr/share/novnc',
 
60
               help='Run webserver on same port. Serve files from DIR.'),
 
61
    cfg.StrOpt('novncproxy_host',
 
62
               default='0.0.0.0',
 
63
               help='Host on which to listen for incoming requests'),
 
64
    cfg.IntOpt('novncproxy_port',
 
65
               default=6080,
 
66
               help='Port on which to listen for incoming requests'),
 
67
    ]
 
68
FLAGS = flags.FLAGS
 
69
FLAGS.register_cli_opts(opts)
 
70
LOG = logging.getLogger(__name__)
 
71
 
 
72
 
 
73
class NovaWebSocketProxy(websockify.WebSocketProxy):
 
74
    def __init__(self, *args, **kwargs):
 
75
        websockify.WebSocketProxy.__init__(self, unix_target=None,
 
76
                                           ssl_target=None, *args, **kwargs)
 
77
 
 
78
    def new_client(self):
 
79
        """
 
80
        Called after a new WebSocket connection has been established.
 
81
        """
 
82
        cookie = Cookie.SimpleCookie()
 
83
        cookie.load(self.headers.getheader('cookie'))
 
84
        token = cookie['token'].value
 
85
        ctxt = context.get_admin_context()
 
86
        connect_info = rpc.call(ctxt, 'consoleauth',
 
87
                                {'method': 'check_token',
 
88
                                 'args': {'token': token}})
 
89
 
 
90
        if not connect_info:
 
91
            LOG.audit("Invalid Token: %s", token)
 
92
            raise Exception("Invalid Token")
 
93
 
 
94
        host = connect_info['host']
 
95
        port = int(connect_info['port'])
 
96
 
 
97
        # Connect to the target
 
98
        self.msg("connecting to: %s:%s" % (host, port))
 
99
        LOG.audit("connecting to: %s:%s" % (host, port))
 
100
        tsock = self.socket(host, port, connect=True)
 
101
 
 
102
        # Handshake as necessary
 
103
        if connect_info.get('internal_access_path'):
 
104
            tsock.send("CONNECT %s HTTP/1.1\r\n\r\n" %
 
105
                        connect_info['internal_access_path'])
 
106
            while True:
 
107
                data = tsock.recv(4096, socket.MSG_PEEK)
 
108
                if data.find("\r\n\r\n") != -1:
 
109
                    if not data.split("\r\n")[0].find("200"):
 
110
                        LOG.audit("Invalid Connection Info %s", token)
 
111
                        raise Exception("Invalid Connection Info")
 
112
                    tsock.recv(len(data))
 
113
                    break
 
114
 
 
115
        if self.verbose and not self.daemon:
 
116
            print(self.traffic_legend)
 
117
 
 
118
        # Start proxying
 
119
        try:
 
120
            self.do_proxy(tsock)
 
121
        except Exception:
 
122
            if tsock:
 
123
                tsock.shutdown(socket.SHUT_RDWR)
 
124
                tsock.close()
 
125
                self.vmsg("%s:%s: Target closed" % (host, port))
 
126
                LOG.audit("%s:%s: Target closed" % (host, port))
 
127
            raise
 
128
 
 
129
 
 
130
if __name__ == '__main__':
 
131
    if FLAGS.ssl_only and not os.path.exists(FLAGS.cert):
 
132
        parser.error("SSL only and %s not found" % FLAGS.cert)
 
133
 
 
134
    # Setup flags
 
135
    flags.parse_args(sys.argv)
 
136
 
 
137
    # Check to see if novnc html/js/css files are present
 
138
    if not os.path.exists(FLAGS.web):
 
139
        print "Can not find novnc html/js/css files at %s." % FLAGS.web
 
140
        sys.exit(-1)
 
141
 
 
142
    # Create and start the NovaWebSockets proxy
 
143
    server = NovaWebSocketProxy(listen_host=FLAGS.novncproxy_host,
 
144
                                listen_port=FLAGS.novncproxy_port,
 
145
                                source_is_ipv6=FLAGS.source_is_ipv6,
 
146
                                verbose=FLAGS.verbose,
 
147
                                cert=FLAGS.cert,
 
148
                                key=FLAGS.key,
 
149
                                ssl_only=FLAGS.ssl_only,
 
150
                                daemon=FLAGS.daemon,
 
151
                                record=FLAGS.record,
 
152
                                web=FLAGS.web,
 
153
                                target_host='ignore',
 
154
                                target_port='ignore',
 
155
                                wrap_mode='exit',
 
156
                                wrap_cmd=None)
 
157
    server.start_server()