Exemple #1
0
 def test_customized_options(self):
     self.update_settings({
         'jujugui.charmstore_url': 'http://1.2.3.4/cs-api',
         'jujugui.plans_url': 'http://1.2.3.4/plans-api',
         'jujugui.terms_url': 'http://1.2.3.4/terms-api',
         'jujugui.GTM_enabled': 'true',
         'jujugui.sandbox': 'true',
         'jujugui.auth': 'blob',
         'jujugui.user': '******',
         'jujugui.password': '******',
         'jujugui.insecure': 'true',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('http://1.2.3.4/cs-api', config['charmstoreURL'])
     self.assertEqual('http://1.2.3.4/plans-api', config['plansURL'])
     self.assertEqual('http://1.2.3.4/terms-api', config['termsURL'])
     self.assertTrue(config['GTM_enabled'])
     self.assertEqual('blob', config['auth'])
     # Note that here we are testing that the value is actually True or
     # False, not that it just evaluates to True/False(like in assertTrue).
     self.assertIs(True, config['sandbox'])
     # User/password values that are explitly set trump defaults.
     self.assertEqual('who', config['user'])
     self.assertEqual('secret', config['password'])
Exemple #2
0
 def test_customized_options(self):
     self.update_settings({
         'jujugui.auth': 'blob',
         'jujugui.charmstore_url': 'http://1.2.3.4/cs-api',
         'jujugui.discharge_token': 'my_discharge_token',
         'jujugui.gisf': 'true',
         'jujugui.GTM_enabled': 'true',
         'jujugui.insecure': 'true',
         'jujugui.password': '******',
         'jujugui.plans_url': 'http://1.2.3.4/plans-api',
         'jujugui.terms_url': 'http://1.2.3.4/terms-api',
         'jujugui.user': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('http://1.2.3.4/cs-api', config['charmstoreURL'])
     self.assertEqual('http://1.2.3.4/plans-api', config['plansURL'])
     self.assertEqual('http://1.2.3.4/terms-api', config['termsURL'])
     self.assertTrue(config['GTM_enabled'])
     self.assertEqual('blob', config['auth'])
     # User/password values that are explitly set trump defaults.
     self.assertEqual('who', config['user'])
     self.assertEqual('secret', config['password'])
     self.assertEqual('my_discharge_token', config['dischargeToken'])
     self.assertEqual('/logout', config['gisfLogout'])
Exemple #3
0
 def test_explicit_base_url(self):
     self.update_settings({'jujugui.base_url': '/ignore/prefix'})
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('sandbox', config['jujuEnvUUID'])
     self.assertEqual('/ignore/prefix', config['baseUrl'])
Exemple #4
0
 def test_explicit_base_url(self):
     self.update_settings({'jujugui.base_url': '/ignore/prefix'})
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('sandbox', config['jujuEnvUUID'])
     self.assertEqual('/ignore/prefix', config['baseUrl'])
Exemple #5
0
 def test_customized_options(self):
     self.update_settings({
         'jujugui.charmstore_url': 'http://1.2.3.4/cs-api',
         'jujugui.plans_url': 'http://1.2.3.4/plans-api',
         'jujugui.terms_url': 'http://1.2.3.4/terms-api',
         'jujugui.GTM_enabled': 'true',
         'jujugui.sandbox': 'true',
         'jujugui.auth': 'blob',
         'jujugui.user': '******',
         'jujugui.password': '******',
         'jujugui.insecure': 'true',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('http://1.2.3.4/cs-api', config['charmstoreURL'])
     self.assertEqual('http://1.2.3.4/plans-api', config['plansURL'])
     self.assertEqual('http://1.2.3.4/terms-api', config['termsURL'])
     self.assertTrue(config['GTM_enabled'])
     self.assertEqual('blob', config['auth'])
     # Note that here we are testing that the value is actually True or
     # False, not that it just evaluates to True/False(like in assertTrue).
     self.assertIs(True, config['sandbox'])
     # User/password values that are explitly set trump defaults.
     self.assertEqual('who', config['user'])
     self.assertEqual('secret', config['password'])
Exemple #6
0
 def test_customized_options(self):
     self.update_settings({
         'jujugui.auth': 'blob',
         'jujugui.charmstore_url': 'http://1.2.3.4/cs-api',
         'jujugui.discharge_token': 'my_discharge_token',
         'jujugui.gisf': 'true',
         'jujugui.jujushellURL': 'https://shell.example.com',
         'jujugui.gisflogout_url': '/logout',
         'jujugui.GTM_enabled': 'true',
         'jujugui.insecure': 'true',
         'jujugui.password': '******',
         'jujugui.plans_url': 'http://1.2.3.4/plans-api/',
         'jujugui.stats_url': '/_stats',
         'jujugui.terms_url': 'http://1.2.3.4/terms-api',
         'jujugui.user': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('https://shell.example.com', config['jujushellURL'])
     self.assertEqual('http://1.2.3.4/cs-api/', config['charmstoreURL'])
     self.assertEqual('http://1.2.3.4/plans-api/', config['plansURL'])
     self.assertEqual('/_stats', config['statsURL'])
     self.assertEqual('http://1.2.3.4/terms-api/', config['termsURL'])
     self.assertTrue(config['GTM_enabled'])
     self.assertEqual('blob', config['auth'])
     # User/password values that are explitly set trump defaults.
     self.assertEqual('who', config['user'])
     self.assertEqual('secret', config['password'])
     self.assertEqual('my_discharge_token', config['dischargeToken'])
     self.assertEqual('/logout', config['gisfLogout'])
Exemple #7
0
 def test_credentials(self):
     self.update_settings({
         'jujugui.user': '******',
         'jujugui.password': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('dalek', config['user'])
     self.assertEqual('exterminate!', config['password'])
Exemple #8
0
 def test_credentials(self):
     self.update_settings({
         'jujugui.user': '******',
         'jujugui.password': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('dalek', config['user'])
     self.assertEqual('exterminate!', config['password'])
Exemple #9
0
 def test_standalone(self):
     self.update_settings({'jujugui.cachebuster': 'foo'})
     jujugui.make_application(self.config)
     expected_context = {
         'config_url': '/config.js',
         'convoy_url': '/foo/combo',
         'raw': False,
         'combine': True,
     }
     context = views.app(self.request)
     self.assertEqual(expected_context, context)
Exemple #10
0
 def test_standalone(self):
     self.update_settings({'jujugui.cachebuster': 'foo'})
     jujugui.make_application(self.config)
     expected_context = {
         'config_url': '/config.js',
         'convoy_url': '/foo/combo',
         'raw': False,
         'logo_url': '',
         'combine': True,
     }
     context = views.app(self.request)
     self.assertEqual(expected_context, context)
Exemple #11
0
 def test_credentials(self):
     self.update_settings({
         'jujugui.user': '******',
         'jujugui.password': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     # When sandbox mode is disabled, the real credentials are provided.
     self.assertIs(False, config['sandbox'])
     self.assertEqual('dalek', config['user'])
     self.assertEqual('exterminate!', config['password'])
Exemple #12
0
 def test_credentials(self):
     self.update_settings({
         'jujugui.user': '******',
         'jujugui.password': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     # When sandbox mode is disabled, the real credentials are provided.
     self.assertIs(False, config['sandbox'])
     self.assertEqual('dalek', config['user'])
     self.assertEqual('exterminate!', config['password'])
Exemple #13
0
 def test_default_options(self):
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('wss', config['socket_protocol'])
     self.assertEqual(
         options.DEFAULT_CHARMSTORE_URL, config['charmstoreURL'])
     self.assertFalse(config['GTM_enabled'])
     # Note that here we are testing that the value is actually True or
     # False, not that it just evaluates to True/False(like in assertTrue).
     self.assertIs(True, config['consoleEnabled'])
     self.assertEqual('', config['jujuCoreVersion'])
     self.assertIs(False, config['sandbox'])
     self.assertEqual('', config['user'])
     self.assertIsNone(config['password'])
     self.assertEqual('', config['baseUrl'])
     self.assertIsNone(config['auth'])
Exemple #14
0
 def test_default_options(self):
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('wss', config['socket_protocol'])
     self.assertEqual(options.DEFAULT_CHARMSTORE_URL,
                      config['charmstoreURL'])
     self.assertFalse(config['GTM_enabled'])
     # Note that here we are testing that the value is actually True or
     # False, not that it just evaluates to True/False(like in assertTrue).
     self.assertIs(True, config['consoleEnabled'])
     self.assertEqual('', config['jujuCoreVersion'])
     self.assertIs(False, config['sandbox'])
     self.assertIsNone(config['user'])
     self.assertIsNone(config['password'])
     self.assertEqual('', config['baseUrl'])
     self.assertIsNone(config['auth'])
     self.assertEqual('wss', config['socket_protocol'])
Exemple #15
0
 def test_customized_options(self):
     self.update_settings({
         'jujugui.charmstore_url': '1.2.3.4/api',
         'jujugui.GTM_enabled': 'true',
         'jujugui.sandbox': 'true',
         'jujugui.auth': 'blob',
         'jujugui.user': '******',
         'jujugui.password': '******',
     })
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('1.2.3.4/api', config['charmstoreURL'])
     self.assertTrue(config['GTM_enabled'])
     self.assertEqual('blob', config['auth'])
     # Note that here we are testing that the value is actually True or
     # False, not that it just evaluates to True/False(like in assertTrue).
     self.assertIs(True, config['sandbox'])
     # The hideLoginButton, user and password values reflect sandbox status.
     self.assertEqual('admin', config['user'])
     self.assertEqual('password', config['password'])
Exemple #16
0
 def test_version(self):
     expected_version = pkg_resources.get_distribution('jujugui').version
     jujugui.make_application(self.config)
     version = views.version(self.request).get('version')
     self.assertEqual(expected_version, version)
Exemple #17
0
 def test_cache_busting_defaults_to_version(self):
     jujugui.make_application(self.config)
     version = views.VERSION
     expected_convoy_url = '/{}/combo'.format(version)
     convoy_url = views.app(self.request)['convoy_url']
     self.assertEqual(expected_convoy_url, convoy_url)
Exemple #18
0
def server():
    """Return the main server application.

    The server app is responsible for serving the WebSocket connection, the
    Juju GUI static files and the main index file for dynamic URLs.
    """
    # Set up the bundle deployer.
    deployer = Deployer(options.apiurl, options.apiversion,
                        options.charmworldurl)
    # Set up handlers.
    server_handlers = []
    if options.sandbox:
        # Sandbox mode.
        server_handlers.append((r'^/ws(?:/.*)?$', handlers.SandboxHandler, {}))
    else:
        # Real environment.
        is_legacy_juju = LooseVersion(options.jujuversion) < LooseVersion('2')
        tokens = auth.AuthenticationTokenHandler()
        auth_backend = auth.get_backend(options.apiversion)
        ws_model_target_template = WEBSOCKET_MODEL_TARGET_TEMPLATE
        if is_legacy_juju:
            ws_model_target_template = WEBSOCKET_TARGET_TEMPLATE_PRE2
        else:
            # Register the WebSocket handler for the controller connection.
            websocket_controller_handler_options = {
                # The Juju API backend url.
                'apiurl': options.apiurl,
                # The backend to use for user authentication.
                'auth_backend': auth_backend,
                # The Juju deployer to use for importing bundles.
                'deployer': deployer,
                # The tokens collection for authentication token requests.
                'tokens': tokens,
                # The WebSocket URL template the browser uses for connecting.
                'ws_source_template': WEBSOCKET_CONTROLLER_SOURCE_TEMPLATE,
                # The WebSocket URL template used for connecting to Juju.
                'ws_target_template': WEBSOCKET_CONTROLLER_TARGET_TEMPLATE,
            }
            server_handlers.append(
                (r'^/ws/controller-api(?:/.*)?$', handlers.WebSocketHandler,
                 websocket_controller_handler_options))
        websocket_model_handler_options = {
            # The Juju API backend url.
            'apiurl': options.apiurl,
            # The backend to use for user authentication.
            'auth_backend': auth_backend,
            # The Juju deployer to use for importing bundles.
            'deployer': deployer,
            # The tokens collection for authentication token requests.
            'tokens': tokens,
            # The WebSocket URL template the browser uses for the connection.
            'ws_source_template': WEBSOCKET_MODEL_SOURCE_TEMPLATE,
            # The WebSocket URL template used for connecting to Juju.
            'ws_target_template': ws_model_target_template,
        }
        juju_proxy_handler_options = {
            'target_url': utils.ws_to_http(options.apiurl),
            'charmworld_url': options.charmworldurl,
        }
        server_handlers.extend([
            # Handle WebSocket connections to the Juju model.
            (r'^/ws/model-api(?:/.*)?$', handlers.WebSocketHandler,
             websocket_model_handler_options),
            # Handle connections to the juju-core HTTPS server.
            # The juju-core HTTPS and WebSocket servers share the same URL.
            (r'^/juju-core/(.*)', handlers.JujuProxyHandler,
             juju_proxy_handler_options),
        ])
    if options.testsroot:
        params = {'path': options.testsroot, 'default_filename': 'index.html'}
        server_handlers.append(
            # Serve the Juju GUI tests.
            (r'^/test/(.*)', web.StaticFileHandler, params), )
    info_handler_options = {
        'apiurl': options.apiurl,
        'apiversion': options.apiversion,
        'deployer': deployer,
        'sandbox': options.sandbox,
        'start_time': int(time.time()),
    }
    wsgi_settings = {
        'jujugui.apiAddress': options.apiurl,
        'jujugui.combine': not options.jujuguidebug,
        'jujugui.gisf': options.gisf,
        'jujugui.GTM_enabled': options.gtm,
        'jujugui.gzip': options.gzip,
        'jujugui.insecure': options.insecure,
        'jujugui.interactive_login': options.interactivelogin,
        'jujugui.bundleservice_url': options.bundleservice_url,
        'jujugui.charmstore_url': options.charmstoreurl,
        'jujugui.jujuCoreVersion': options.jujuversion,
        'jujugui.raw': options.jujuguidebug,
        'jujugui.sandbox': options.sandbox,
        'jujugui.controllerSocketTemplate':
        (WEBSOCKET_CONTROLLER_SOURCE_TEMPLATE),
        'jujugui.socketTemplate': WEBSOCKET_MODEL_SOURCE_TEMPLATE,
        'jujugui.uuid': options.uuid,
    }
    if options.password:
        wsgi_settings['jujugui.password'] = options.password
    config = Configurator(settings=wsgi_settings)
    wsgi_app = WSGIContainer(make_application(config))
    server_handlers.extend([
        # Handle GUI server info.
        (r'^/gui-server-info', handlers.InfoHandler, info_handler_options),
        (r".*", web.FallbackHandler, dict(fallback=wsgi_app))
    ])
    return web.Application(server_handlers, debug=options.debug)
Exemple #19
0
def server():
    """Return the main server application.

    The server app is responsible for serving the WebSocket connection, the
    Juju GUI static files and the main index file for dynamic URLs.
    """
    # Set up the bundle deployer.
    deployer = Deployer(options.apiurl, options.apiversion, options.charmworldurl)
    # Set up handlers.
    server_handlers = []
    if options.sandbox:
        # Sandbox mode.
        server_handlers.append((r"^/ws(?:/.*)?$", handlers.SandboxHandler, {}))
    else:
        # Real environment.
        is_legacy_juju = LooseVersion(options.jujuversion) < LooseVersion("2")
        tokens = auth.AuthenticationTokenHandler()
        auth_backend = auth.get_backend(options.apiversion)
        ws_model_target_template = WEBSOCKET_MODEL_TARGET_TEMPLATE
        if is_legacy_juju:
            ws_model_target_template = WEBSOCKET_TARGET_TEMPLATE_PRE2
        else:
            # Register the WebSocket handler for the controller connection.
            websocket_controller_handler_options = {
                # The Juju API backend url.
                "apiurl": options.apiurl,
                # The backend to use for user authentication.
                "auth_backend": auth_backend,
                # The Juju deployer to use for importing bundles.
                "deployer": deployer,
                # The tokens collection for authentication token requests.
                "tokens": tokens,
                # The WebSocket URL template the browser uses for connecting.
                "ws_source_template": WEBSOCKET_CONTROLLER_SOURCE_TEMPLATE,
                # The WebSocket URL template used for connecting to Juju.
                "ws_target_template": WEBSOCKET_CONTROLLER_TARGET_TEMPLATE,
            }
            server_handlers.append(
                (r"^/ws/controller-api(?:/.*)?$", handlers.WebSocketHandler, websocket_controller_handler_options)
            )
        websocket_model_handler_options = {
            # The Juju API backend url.
            "apiurl": options.apiurl,
            # The backend to use for user authentication.
            "auth_backend": auth_backend,
            # The Juju deployer to use for importing bundles.
            "deployer": deployer,
            # The tokens collection for authentication token requests.
            "tokens": tokens,
            # The WebSocket URL template the browser uses for the connection.
            "ws_source_template": WEBSOCKET_MODEL_SOURCE_TEMPLATE,
            # The WebSocket URL template used for connecting to Juju.
            "ws_target_template": ws_model_target_template,
        }
        juju_proxy_handler_options = {
            "target_url": utils.ws_to_http(options.apiurl),
            "charmworld_url": options.charmworldurl,
        }
        server_handlers.extend(
            [
                # Handle WebSocket connections to the Juju model.
                (r"^/ws/model-api(?:/.*)?$", handlers.WebSocketHandler, websocket_model_handler_options),
                # Handle connections to the juju-core HTTPS server.
                # The juju-core HTTPS and WebSocket servers share the same URL.
                (r"^/juju-core/(.*)", handlers.JujuProxyHandler, juju_proxy_handler_options),
            ]
        )
    if options.testsroot:
        params = {"path": options.testsroot, "default_filename": "index.html"}
        server_handlers.append(
            # Serve the Juju GUI tests.
            (r"^/test/(.*)", web.StaticFileHandler, params)
        )
    info_handler_options = {
        "apiurl": options.apiurl,
        "apiversion": options.apiversion,
        "deployer": deployer,
        "sandbox": options.sandbox,
        "start_time": int(time.time()),
    }
    wsgi_settings = {
        "jujugui.apiAddress": options.apiurl,
        "jujugui.combine": not options.jujuguidebug,
        "jujugui.gisf": options.gisf,
        "jujugui.GTM_enabled": options.gtm,
        "jujugui.gzip": options.gzip,
        "jujugui.insecure": options.insecure,
        "jujugui.interactive_login": options.interactivelogin,
        "jujugui.bundleservice_url": options.bundleservice_url,
        "jujugui.charmstore_url": options.charmstoreurl,
        "jujugui.jujuCoreVersion": options.jujuversion,
        "jujugui.raw": options.jujuguidebug,
        "jujugui.sandbox": options.sandbox,
        "jujugui.controllerSocketTemplate": (WEBSOCKET_CONTROLLER_SOURCE_TEMPLATE),
        "jujugui.socketTemplate": WEBSOCKET_MODEL_SOURCE_TEMPLATE,
        "jujugui.uuid": options.uuid,
    }
    if options.password:
        wsgi_settings["jujugui.password"] = options.password
    config = Configurator(settings=wsgi_settings)
    wsgi_app = WSGIContainer(make_application(config))
    server_handlers.extend(
        [
            # Handle GUI server info.
            (r"^/gui-server-info", handlers.InfoHandler, info_handler_options),
            (r".*", web.FallbackHandler, dict(fallback=wsgi_app)),
        ]
    )
    return web.Application(server_handlers, debug=options.debug)
Exemple #20
0
 def test_cache_busting_defaults_to_version(self):
     jujugui.make_application(self.config)
     version = views.VERSION
     expected_convoy_url = '/{}/combo'.format(version)
     convoy_url = views.app(self.request)['convoy_url']
     self.assertEqual(expected_convoy_url, convoy_url)
Exemple #21
0
 def test_standalone(self):
     jujugui.make_application(self.config)
     response = views.config(self.request)
     config = self.check_response(response)
     self.assertEqual('sandbox', config['jujuEnvUUID'])
     self.assertEqual('', config['baseUrl'])
Exemple #22
0
 def test_version(self):
     expected_version = pkg_resources.get_distribution('jujugui').version
     jujugui.make_application(self.config)
     version = views.version(self.request).get('version')
     self.assertEqual(expected_version, version)
Exemple #23
0
def server():
    """Return the main server application.

    The server app is responsible for serving the WebSocket connection, the
    Juju GUI static files and the main index file for dynamic URLs.
    """
    # Set up the bundle deployer.
    deployer = Deployer(options.apiurl, options.apiversion,
                        options.charmworldurl)
    # Set up handlers.
    server_handlers = []
    if options.sandbox:
        # Sandbox mode.
        server_handlers.append(
            (r'^/ws(?:/.*)?$', handlers.SandboxHandler, {}))
    else:
        # Real environment.
        ws_target_template = WEBSOCKET_TARGET_TEMPLATE
        if LooseVersion(options.jujuversion) < LooseVersion('2'):
            ws_target_template = WEBSOCKET_TARGET_TEMPLATE_PRE2
        tokens = auth.AuthenticationTokenHandler()
        websocket_handler_options = {
            # The Juju API backend url.
            'apiurl': options.apiurl,
            # The backend to use for user authentication.
            'auth_backend': auth.get_backend(options.apiversion),
            # The Juju deployer to use for importing bundles.
            'deployer': deployer,
            # The tokens collection for authentication token requests.
            'tokens': tokens,
            # The WebSocket URL template the browser uses for the connection.
            'ws_source_template': WEBSOCKET_SOURCE_TEMPLATE,
            # The WebSocket URL template used for connecting to Juju.
            'ws_target_template': ws_target_template,
        }
        juju_proxy_handler_options = {
            'target_url': utils.ws_to_http(options.apiurl),
            'charmworld_url': options.charmworldurl,
        }
        server_handlers.extend([
            # Handle WebSocket connections.
            (r'^/ws(?:/.*)?$', handlers.WebSocketHandler,
                websocket_handler_options),
            # Handle connections to the juju-core HTTPS server.
            # The juju-core HTTPS and WebSocket servers share the same URL.
            (r'^/juju-core/(.*)', handlers.JujuProxyHandler,
             juju_proxy_handler_options),
        ])
    if options.testsroot:
        params = {'path': options.testsroot, 'default_filename': 'index.html'}
        server_handlers.append(
            # Serve the Juju GUI tests.
            (r'^/test/(.*)', web.StaticFileHandler, params),
        )
    info_handler_options = {
        'apiurl': options.apiurl,
        'apiversion': options.apiversion,
        'deployer': deployer,
        'sandbox': options.sandbox,
        'start_time': int(time.time()),
    }
    wsgi_settings = {
        'jujugui.apiAddress': options.apiurl,
        'jujugui.combine': not options.jujuguidebug,
        'jujugui.gisf': options.gisf,
        'jujugui.GTM_enabled': options.gtm,
        'jujugui.gzip': options.gzip,
        'jujugui.insecure': options.insecure,
        'jujugui.interactive_login': options.interactivelogin,
        'jujugui.jem_url': options.jemurl,
        'jujugui.charmstore_url': options.charmstoreurl,
        'jujugui.jujuCoreVersion': options.jujuversion,
        'jujugui.raw': options.jujuguidebug,
        'jujugui.sandbox': options.sandbox,
        'jujugui.socketTemplate': WEBSOCKET_SOURCE_TEMPLATE,
        'jujugui.uuid': options.uuid,
    }
    if options.password:
        wsgi_settings['jujugui.password'] = options.password
    config = Configurator(settings=wsgi_settings)
    wsgi_app = WSGIContainer(make_application(config))
    server_handlers.extend([
        # Handle GUI server info.
        (r'^/gui-server-info', handlers.InfoHandler, info_handler_options),
        (r".*", web.FallbackHandler, dict(fallback=wsgi_app))
    ])
    return web.Application(server_handlers, debug=options.debug)