Пример #1
0
    def delete_node(self, lb_id, node_id):
        """
        Determines whether the node to be deleted exists in the session store,
        deletes the node, and returns the response code.
        """
        current_timestamp = self.clock.seconds()
        if lb_id in self.lbs:

            _verify_and_update_lb_state(self, lb_id, False, current_timestamp)

            if self.lbs[lb_id]["status"] != "ACTIVE":
                # Error message verified as of 2015-04-22
                return considered_immutable_error(self.lbs[lb_id]["status"],
                                                  lb_id)

            _verify_and_update_lb_state(self,
                                        lb_id,
                                        current_timestamp=current_timestamp)

            if _delete_node(self, lb_id, node_id):
                return None, 202
            else:
                return not_found_response("node"), 404

        return not_found_response("loadbalancer"), 404
Пример #2
0
    def update_node(self, lb_id, node_id, node_updates):
        """
        Update the weight, condition, or type of a single node.  The IP, port,
        status, and ID are immutable, and attempting to change them will cause
        a 400 response to be returned.

        All success and error behavior verified as of 2016-06-16.

        :param str lb_id: the load balancer ID
        :param str node_id: the node ID to update
        :param dict node_updates: The JSON dictionary containing node
            attributes to update
        :param current_timestamp: What the current time is

        :return: a `tuple` of (json response as a dict, http status code)
        """
        feed_summary = (
            "Node successfully updated with address: '{address}', port: '{port}', "
            "weight: '{weight}', condition: '{condition}'")
        # first, store whether address and port were provided - if they were
        # that's a validation error not a schema error
        things_wrong = {k: True for k in ("address", "port", "id")
                        if k in node_updates}
        node_updates = {k: node_updates[k] for k in node_updates
                        if k not in ("address", "port")}
        # use the Node.from_json to check the schema
        try:
            Node.from_json(dict(address="1.1.1.1", port=80, **node_updates))
        except (TypeError, ValueError):
            return invalid_json_schema()

        # handle the possible validation (as opposed to schema) errors
        if not 1 <= node_updates.get('weight', 1) <= 100:
            things_wrong["weight"] = True
        if things_wrong:
            return updating_node_validation_error(**things_wrong)

        # Now, finally, check if the LB exists and node exists
        if lb_id in self.lbs:
            self._verify_and_update_lb_state(lb_id, False, self.clock.seconds())

            if self.lbs[lb_id]["status"] != "ACTIVE":
                return considered_immutable_error(
                    self.lbs[lb_id]["status"], lb_id)

            for i, node in enumerate(self.lbs[lb_id].nodes):
                if node.id == node_id:
                    params = attr.asdict(node)
                    params.update(node_updates)
                    self.lbs[lb_id].nodes[i] = Node(**params)
                    self.lbs[lb_id].nodes[i].feed_events.append(
                        (feed_summary.format(**params),
                         seconds_to_timestamp(self.clock.seconds())))
                    return ("", 202)

            return node_not_found()

        return loadbalancer_not_found()
Пример #3
0
    def update_node(self, lb_id, node_id, node_updates):
        """
        Update the weight, condition, or type of a single node.  The IP, port,
        status, and ID are immutable, and attempting to change them will cause
        a 400 response to be returned.

        All success and error behavior verified as of 2016-06-16.

        :param str lb_id: the load balancer ID
        :param str node_id: the node ID to update
        :param dict node_updates: The JSON dictionary containing node
            attributes to update
        :param current_timestamp: What the current time is

        :return: a `tuple` of (json response as a dict, http status code)
        """
        feed_summary = (
            "Node successfully updated with address: '{address}', port: '{port}', "
            "weight: '{weight}', condition: '{condition}'")
        # first, store whether address and port were provided - if they were
        # that's a validation error not a schema error
        things_wrong = dict([(k, True) for k in ("address", "port", "id")
                             if k in node_updates])
        node_updates = dict([(k, v) for k, v in node_updates.items()
                             if k not in ("address", "port")])
        # use the Node.from_json to check the schema
        try:
            Node.from_json(dict(address="1.1.1.1", port=80, **node_updates))
        except (TypeError, ValueError):
            return invalid_json_schema()

        # handle the possible validation (as opposed to schema) errors
        if not 1 <= node_updates.get('weight', 1) <= 100:
            things_wrong["weight"] = True
        if things_wrong:
            return updating_node_validation_error(**things_wrong)

        # Now, finally, check if the LB exists and node exists
        if lb_id in self.lbs:
            self._verify_and_update_lb_state(lb_id, False, self.clock.seconds())

            if self.lbs[lb_id]["status"] != "ACTIVE":
                return considered_immutable_error(
                    self.lbs[lb_id]["status"], lb_id)

            for i, node in enumerate(self.lbs[lb_id].nodes):
                if node.id == node_id:
                    params = attr.asdict(node)
                    params.update(node_updates)
                    self.lbs[lb_id].nodes[i] = Node(**params)
                    self.lbs[lb_id].nodes[i].feed_events.append(
                        (feed_summary.format(**params),
                         seconds_to_timestamp(self.clock.seconds())))
                    return ("", 202)

            return node_not_found()

        return loadbalancer_not_found()
Пример #4
0
    def add_node(self, node_list, lb_id):
        """
        Add one or more nodes to a load balancer.  Fails if one or more of the
        nodes provided has the same address/port as an existing node.  Also
        fails if adding the nodes would exceed the maximum number of nodes on
        the CLB.

        :param list node_list: a `list` of `dict` containing specification for
            nodes

        :return: a `tuple` of (json response as a dict, http status code)
        """
        if lb_id in self.lbs:
            current_timestamp = self.clock.seconds()
            self._verify_and_update_lb_state(lb_id, False, current_timestamp)

            if self.lbs[lb_id]["status"] != "ACTIVE":
                return considered_immutable_error(
                    self.lbs[lb_id]["status"], lb_id)

            nodes = [Node.from_json(blob) for blob in node_list]

            for existing_node in self.lbs[lb_id].nodes:
                for new_node in nodes:
                    if existing_node.same_as(new_node):
                        resource = invalid_resource(
                            "Duplicate nodes detected. One or more nodes "
                            "already configured on load balancer.", 413)
                        return (resource, 413)

            # If there were no duplicates
            new_nodeCount = len(self.lbs[lb_id].nodes) + len(nodes)
            if new_nodeCount <= self.node_limit:
                self.lbs[lb_id].nodes = self.lbs[lb_id].nodes + nodes
            else:
                resource = invalid_resource(
                    "Nodes must not exceed {0} "
                    "per load balancer.".format(self.node_limit), 413)
                return (resource, 413)

            # Node status will be OFFLINE if health monitor is enabled in CLB
            # ONLINE if health monitor is disabled
            if self.lbs[lb_id].health_monitor != {}:
                for node in nodes:
                    node.status = "OFFLINE"

            self._add_node_created_feeds(nodes)

            self._verify_and_update_lb_state(
                lb_id, current_timestamp=current_timestamp)
            return {"nodes": [node.as_json() for node in nodes]}, 202

        return not_found_response("loadbalancer"), 404
Пример #5
0
    def add_node(self, node_list, lb_id):
        """
        Add one or more nodes to a load balancer.  Fails if one or more of the
        nodes provided has the same address/port as an existing node.  Also
        fails if adding the nodes would exceed the maximum number of nodes on
        the CLB.

        :param list node_list: a `list` of `dict` containing specification for
            nodes

        :return: a `tuple` of (json response as a dict, http status code)
        """
        if lb_id in self.lbs:
            current_timestamp = self.clock.seconds()
            self._verify_and_update_lb_state(lb_id, False, current_timestamp)

            if self.lbs[lb_id]["status"] != "ACTIVE":
                return considered_immutable_error(self.lbs[lb_id]["status"],
                                                  lb_id)

            nodes = [Node.from_json(blob) for blob in node_list]

            for existing_node in self.lbs[lb_id].nodes:
                for new_node in nodes:
                    if existing_node.same_as(new_node):
                        resource = invalid_resource(
                            "Duplicate nodes detected. One or more nodes "
                            "already configured on load balancer.", 413)
                        return (resource, 413)

            # If there were no duplicates
            new_nodeCount = len(self.lbs[lb_id].nodes) + len(nodes)
            if new_nodeCount <= self.node_limit:
                self.lbs[lb_id].nodes = self.lbs[lb_id].nodes + nodes
            else:
                resource = invalid_resource(
                    "Nodes must not exceed {0} "
                    "per load balancer.".format(self.node_limit), 413)
                return (resource, 413)

            # Node status will be OFFLINE if health monitor is enabled in CLB
            # ONLINE if health monitor is disabled
            if self.lbs[lb_id].health_monitor != {}:
                for node in nodes:
                    node.status = "OFFLINE"

            self._add_node_created_feeds(nodes)

            self._verify_and_update_lb_state(
                lb_id, current_timestamp=current_timestamp)
            return {"nodes": [node.as_json() for node in nodes]}, 202

        return not_found_response("loadbalancer"), 404
Пример #6
0
    def delete_node(self, lb_id, node_id):
        """
        Determines whether the node to be deleted exists in the session store,
        deletes the node, and returns the response code.
        """
        current_timestamp = self.clock.seconds()
        if lb_id in self.lbs:

            self._verify_and_update_lb_state(lb_id, False, current_timestamp)

            if self.lbs[lb_id]["status"] != "ACTIVE":
                # Error message verified as of 2015-04-22
                return considered_immutable_error(
                    self.lbs[lb_id]["status"], lb_id)

            self._verify_and_update_lb_state(
                lb_id, current_timestamp=current_timestamp)

            if self._delete_node(lb_id, node_id):
                return None, 202
            else:
                return not_found_response("node"), 404

        return not_found_response("loadbalancer"), 404