def assign_ips(self, nodes_ids, network_name): """ Idempotent assignment IP addresses to nodes. All nodes passed as first argument get IP address from network, referred by network_name. If node already has IP address from this network, it remains unchanged. If one of the nodes is the node from other cluster, this func will fail. :param node_ids: List of nodes IDs in database. :type node_ids: list :param network_name: Network name :type network_name: str :returns: None :raises: Exception, errors.AssignIPError """ cluster_id = db().query(Node).get(nodes_ids[0]).cluster_id for node_id in nodes_ids: node = db().query(Node).get(node_id) if node.cluster_id != cluster_id: raise Exception( u"Node id='{0}' doesn't belong to cluster_id='{1}'".format( node_id, cluster_id)) network = db().query(Network).join(NetworkGroup).\ filter(NetworkGroup.cluster_id == cluster_id).\ filter_by(name=network_name).first() if not network: raise errors.AssignIPError( u"Network '%s' for cluster_id=%s not found." % (network_name, cluster_id)) for node_id in nodes_ids: node_ips = imap( lambda i: i.ip_addr, self._get_ips_except_admin(node_id=node_id, network_id=network.id)) # check if any of node_ips in required ranges ip_already_assigned = False for ip in node_ips: if self.check_ip_belongs_to_net(ip, network): logger.info(u"Node id='{0}' already has an IP address " "inside '{1}' network.".format( node_id, network.name)) ip_already_assigned = True break if ip_already_assigned: continue # IP address has not been assigned, let's do it free_ip = self.get_free_ips(network.network_group.id)[0] ip_db = IPAddr(network=network.id, node=node_id, ip_addr=free_ip) db().add(ip_db) db().commit()
def assign_ips(cls, nodes, network_name): """Idempotent assignment IP addresses to nodes. All nodes passed as first argument get IP address from network, referred by network_name. If node already has IP address from this network, it remains unchanged. If one of the nodes is the node from other cluster, this func will fail. :param node_ids: List of nodes IDs in database. :type node_ids: list :param network_name: Network name :type network_name: str :returns: None :raises: Exception, errors.AssignIPError """ cluster_id = nodes[0].cluster_id for node in nodes: if node.cluster_id != cluster_id: raise Exception( u"Node id='{0}' doesn't belong to cluster_id='{1}'".format( node.id, cluster_id)) network_groups = db().query(NetworkGroup).\ filter_by(name=network_name) if not network_groups: raise errors.AssignIPError( u"Network '%s' for cluster_id=%s not found." % (network_name, cluster_id)) # Check which nodes need ips nodes_need_ips = defaultdict(list) for node in nodes: node_id = node.id if network_name == 'public' and \ not objects.Node.should_have_public(node): continue group_id = (node.group_id or objects.Cluster.get_default_group(node.cluster).id) network = network_groups.filter( or_( NetworkGroup.group_id == group_id, NetworkGroup.group_id == None # flake8: noqa )).first() node_ips = imap( lambda i: i.ip_addr, cls._get_ips_except_admin(node_id=node_id, network_id=network.id)) # check if any of node_ips in required ranges ip_already_assigned = False for ip in node_ips: if cls.check_ip_belongs_to_net(ip, network): logger.info(u"Node id='{0}' already has an IP address " "inside '{1}' network.".format( node_id, network.name)) ip_already_assigned = True break if ip_already_assigned: continue nodes_need_ips[network].append(node_id) # Get and assign ips for nodes for network, nodes in six.iteritems(nodes_need_ips): free_ips = cls.get_free_ips(network, len(nodes)) for ip, n in zip(free_ips, nodes): logger.info( "Assigning IP for node '{0}' in network '{1}'".format( n, network_name)) pxeip = cls.get_admin_ip_for_node(n) logger.info("pxeip is {0}".format(pxeip)) newip = cls.handleipgroup(pxeip, ip) logger.info("newip is {0}".format(newip)) ip_db = IPAddr(node=n, ip_addr=newip, network=network.id) db().add(ip_db) db().flush()