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
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()
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()
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
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
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