def update_nodes(cls, instance, nodes_ids): """Update Cluster nodes by specified node IDs Nodes with specified IDs will replace existing ones in Cluster :param instance: Cluster instance :param nodes_ids: list of nodes ids :returns: None """ # TODO(NAME): sepatate nodes # for deletion and addition by set(). new_nodes = [] if nodes_ids: new_nodes = db().query(models.Node).filter( models.Node.id.in_(nodes_ids) ) nodes_to_remove = [n for n in instance.nodes if n not in new_nodes] nodes_to_add = [n for n in new_nodes if n not in instance.nodes] for node in nodes_to_add: if not node.online: raise errors.NodeOffline( u"Cannot add offline node " u"'{0}' to environment".format(node.id) ) # we should reset hostname to default value to guarantee # hostnames uniqueness for nodes outside clusters from nailgun.objects import Node for node in nodes_to_remove: node.hostname = Node.default_slave_name(node) map(instance.nodes.remove, nodes_to_remove) map(instance.nodes.append, nodes_to_add) net_manager = cls.get_network_manager(instance) map( net_manager.clear_assigned_networks, nodes_to_remove ) map( net_manager.clear_bond_configuration, nodes_to_remove ) cls.replace_provisioning_info_on_nodes(instance, [], nodes_to_remove) cls.replace_deployment_info_on_nodes(instance, [], nodes_to_remove) from nailgun.objects import NodeCollection NodeCollection.reset_network_template(nodes_to_remove) map( net_manager.assign_networks_by_default, nodes_to_add ) cls.update_nodes_network_template(instance, nodes_to_add) db().flush()