예제 #1
0
 def setUp(self):
     self.messages = []
     self.handler = type('Handler', (), {
         'connected': True,
         'write_message': self.messages.append
     })()
     self.wrapped = utils.wrap_write_message(self.handler)
예제 #2
0
 def setUp(self):
     self.messages = []
     self.handler = type(
         'Handler', (),
         {'connected': True, 'write_message': self.messages.append}
     )()
     self.wrapped = utils.wrap_write_message(self.handler)
예제 #3
0
 def initialize(self):
     """Set up a fake user and a change set middleware."""
     user = User(
         username='******',
         password='******',
         is_authenticated=True)
     self.changeset = ChangeSetMiddleware(user, wrap_write_message(self))
예제 #4
0
    def on_message(self, message):
        """Hook called when a new message is received from the browser.

        If the message is a deployment request, start the deployment process.
        Otherwise the message is propagated to the Juju API server.
        Messages sent before the client connection to the Juju API server is
        established are queued for later delivery.
        """
        data = json_decode_dict(message)
        encoded = None
        if data is not None:
            # Handle deployment requests.
            if self.deployment.requested(data):
                return self.deployment.process_request(data)
            # Handle authentication requests.
            if not self.user.is_authenticated:
                new_data = self.auth.process_request(data)
                if new_data is None:
                    # The None marker indicates that a response was sent.
                    return
                elif new_data != data:
                    encoded = escape.json_encode(new_data)
                    message = encoded.decode('utf8')
            # Handle authentication token requests.
            if self.tokens.token_requested(data):
                return self.tokens.process_token_request(
                    data, self.user, wrap_write_message(self))
        # Propagate messages to the Juju API server.
        if encoded is None:
            encoded = message.encode('utf-8')
        if self.juju_connected:
            logging.debug(self._summary + 'client -> juju: {}'.format(encoded))
            return self.juju_connection.write_message(message)
        logging.debug(self._summary + 'client -> queue: {}'.format(encoded))
        self._juju_message_queue.append(message)
예제 #5
0
    def initialize(self,
                   apiurl,
                   auth_backend,
                   deployer,
                   tokens,
                   ws_source_template,
                   ws_target_template,
                   io_loop=None):
        """Initialize the WebSocket server.

        Create a new WebSocket client and connect it to the Juju API.
        Set up the authentication system.
        Handle the queued messages.
        """
        if io_loop is None:
            io_loop = IOLoop.current()
        self._io_loop = io_loop
        self._summary = request_summary(self.request) + ' '
        logging.info(self._summary + 'client connected')
        self.connected = True
        self.juju_connected = False
        self._juju_message_queue = queue = deque()
        # Set up the authentication infrastructure.
        self.tokens = tokens
        write_message = wrap_write_message(self)
        self.user = User()
        self.auth = AuthMiddleware(self.user, auth_backend, tokens,
                                   write_message)
        # Set up the bundle deployment and change set infrastructure.
        self.deployment = DeployMiddleware(self.user, deployer, write_message)
        self.changeset = ChangeSetMiddleware(self.user, write_message)
        apiurl = get_juju_api_url(self.request.path, ws_source_template,
                                  ws_target_template, apiurl)
        # Juju requires the Origin header to be included in the WebSocket
        # client handshake request. Propagate the client origin if present;
        # use the Juju API server as origin otherwise.
        headers = get_headers(self.request, apiurl)
        # Connect the WebSocket client to the Juju API server.
        self._juju_connected_future = websocket_connect(io_loop,
                                                        apiurl,
                                                        self.on_juju_message,
                                                        headers=headers)
        try:
            self.juju_connection = yield self._juju_connected_future
        except Exception as err:
            logging.error(self._summary + 'unable to connect to the Juju API')
            logging.exception(err)
            self.connected = False
            return
        # At this point the Juju API is successfully connected.
        self.juju_connected = True
        logging.info(self._summary + 'Juju API connected: {}'.format(apiurl))
        # Send all the messages that have been enqueued before the connection
        # to the Juju API server was established.
        while self.connected and self.juju_connected and len(queue):
            message = queue.popleft()
            encoded = message.encode('utf-8')
            logging.debug(self._summary + 'queue -> juju: {}'.format(encoded))
            self.juju_connection.write_message(message)
예제 #6
0
    def initialize(self, apiurl, auth_backend, deployer, tokens, io_loop=None):
        """Initialize the WebSocket server.

        Create a new WebSocket client and connect it to the Juju API.
        Set up the authentication system.
        Handle the queued messages.
        """
        if io_loop is None:
            io_loop = IOLoop.current()
        self._io_loop = io_loop
        self._summary = request_summary(self.request) + ' '
        logging.info(self._summary + 'client connected')
        self.connected = True
        self.juju_connected = False
        self._juju_message_queue = queue = deque()
        # Set up the authentication infrastructure.
        self.tokens = tokens
        write_message = wrap_write_message(self)
        self.user = User()
        self.auth = AuthMiddleware(
            self.user, auth_backend, tokens, write_message)
        # Set up the bundle deployment and change set infrastructure.
        self.deployment = DeployMiddleware(self.user, deployer, write_message)
        self.changeset = ChangeSetMiddleware(self.user, write_message)
        # XXX The handler is no longer path agnostic, and this can be fixed by
        # capturing the relevant path fragment on the regexp, and then
        # overriding the handler's open method to store the path in the
        # instance.
        path = self.request.path[len('/ws'):]
        if path:
            # If they provided a path in their request then we need to use
            # that api endpoint.
            apiurl = '{}{}'.format(apiurl, path)
        # Juju requires the Origin header to be included in the WebSocket
        # client handshake request. Propagate the client origin if present;
        # use the Juju API server as origin otherwise.
        headers = get_headers(self.request, apiurl)
        # Connect the WebSocket client to the Juju API server.
        self._juju_connected_future = websocket_connect(
            io_loop, apiurl, self.on_juju_message, headers=headers)
        try:
            self.juju_connection = yield self._juju_connected_future
        except Exception as err:
            logging.error(self._summary + 'unable to connect to the Juju API')
            logging.exception(err)
            self.connected = False
            return
        # At this point the Juju API is successfully connected.
        self.juju_connected = True
        logging.info(self._summary + 'Juju API connected')
        # Send all the messages that have been enqueued before the connection
        # to the Juju API server was established.
        while self.connected and self.juju_connected and len(queue):
            message = queue.popleft()
            encoded = message.encode('utf-8')
            logging.debug(self._summary + 'queue -> juju: {}'.format(encoded))
            self.juju_connection.write_message(message)
예제 #7
0
    def initialize(
            self, apiurl, auth_backend, deployer, tokens, ws_source_template,
            ws_target_template, io_loop=None):
        """Initialize the WebSocket server.

        Create a new WebSocket client and connect it to the Juju API.
        Set up the authentication system.
        Handle the queued messages.
        """
        if io_loop is None:
            io_loop = IOLoop.current()
        self._io_loop = io_loop
        self._summary = request_summary(self.request) + ' '
        logging.info(self._summary + 'client connected')
        self.connected = True
        self.juju_connected = False
        self._juju_message_queue = queue = deque()
        # Set up the authentication infrastructure.
        self.tokens = tokens
        write_message = wrap_write_message(self)
        self.user = User()
        self.auth = AuthMiddleware(
            self.user, auth_backend, tokens, write_message)
        # Set up the bundle deployment and change set infrastructure.
        self.deployment = DeployMiddleware(self.user, deployer, write_message)
        self.changeset = ChangeSetMiddleware(self.user, write_message)
        apiurl = get_juju_api_url(
            self.request.path, ws_source_template, ws_target_template, apiurl)
        # Juju requires the Origin header to be included in the WebSocket
        # client handshake request. Propagate the client origin if present;
        # use the Juju API server as origin otherwise.
        headers = get_headers(self.request, apiurl)
        # Connect the WebSocket client to the Juju API server.
        self._juju_connected_future = websocket_connect(
            io_loop, apiurl, self.on_juju_message, headers=headers)
        try:
            self.juju_connection = yield self._juju_connected_future
        except Exception as err:
            logging.error(self._summary + 'unable to connect to the Juju API')
            logging.exception(err)
            self.connected = False
            return
        # At this point the Juju API is successfully connected.
        self.juju_connected = True
        logging.info(self._summary + 'Juju API connected: {}'.format(apiurl))
        # Send all the messages that have been enqueued before the connection
        # to the Juju API server was established.
        while self.connected and self.juju_connected and len(queue):
            message = queue.popleft()
            encoded = message.encode('utf-8')
            logging.debug(self._summary + 'queue -> juju: {}'.format(encoded))
            self.juju_connection.write_message(message)
예제 #8
0
    def on_message(self, message):
        """Hook called when a new message is received from the browser.

        If the message is a change set request, return the resulting changes.
        If the message is a deployment request, start the deployment process.
        Otherwise the message is propagated to the Juju API server.
        Messages sent before the client connection to the Juju API server is
        established are queued for later delivery.
        """
        data = json_decode_dict(message)
        encoded = None
        if data is not None:
            # Handle change set requests.
            if self.changeset.requested(data):
                return self.changeset.process_request(data)
            # Handle deployment requests.
            if self.deployment.requested(data):
                return self.deployment.process_request(data)
            # Handle authentication requests.
            if not self.user.is_authenticated:
                new_data = self.auth.process_request(data)
                if new_data is None:
                    # The None marker indicates that a response was sent.
                    return
                elif new_data != data:
                    encoded = escape.json_encode(new_data)
                    message = encoded.decode('utf8')
            # Handle authentication token requests.
            if self.tokens.token_requested(data):
                return self.tokens.process_token_request(
                    data, self.user, wrap_write_message(self))
        # Propagate messages to the Juju API server.
        if encoded is None:
            encoded = message.encode('utf-8')
        if self.juju_connected:
            logging.debug(self._summary + 'client -> juju: {}'.format(encoded))
            return self.juju_connection.write_message(message)
        logging.debug(self._summary + 'client -> queue: {}'.format(encoded))
        self._juju_message_queue.append(message)
예제 #9
0
 def setUp(self):
     self.messages = []
     self.handler = type("Handler", (), {"connected": True, "write_message": self.messages.append})()
     self.wrapped = utils.wrap_write_message(self.handler)