- def __init__(self, api, node_id_or_hostname_list = None, extra_fields = []):
- self.api = api
-
- sql = "SELECT nodes.*, node_nodenetworks.nodenetwork_id"
-
- # For compatibility and convenience, support returning primary
- # interface values directly in the Node structure.
- extra_nodenetwork_fields = set(extra_fields).intersection(Node.primary_nodenetwork_fields)
-
- # N.B.: Joined IDs may be marked as deleted in their primary tables
- join_tables = {
- # extra_field: (extra_table, extra_column, join_using)
- 'nodegroup_ids': ('nodegroup_nodes', 'nodegroup_id', 'node_id'),
- 'conf_file_ids': ('conf_assoc', 'conf_file_id', 'node_id'),
- 'root_person_ids': ('node_root_access', 'person_id AS root_person_id', 'node_id'),
- 'slice_ids': ('dslice03_slicenode', 'slice_id', 'node_id'),
- 'pcu_ids': ('pcu_ports', 'pcu_id', 'node_id'),
- }
-
- extra_fields = filter(join_tables.has_key, extra_fields)
- extra_tables = ["%s USING (%s)" % \
- (join_tables[field][0], join_tables[field][2]) \
- for field in extra_fields]
- extra_columns = ["%s.%s" % \
- (join_tables[field][0], join_tables[field][1]) \
- for field in extra_fields]
-
- if extra_columns:
- sql += ", " + ", ".join(extra_columns)
-
- sql += " FROM nodes" \
- " LEFT JOIN node_nodenetworks USING (node_id)"
-
- if extra_tables:
- sql += " LEFT JOIN " + " LEFT JOIN ".join(extra_tables)
-
- sql += " WHERE deleted IS False"
-
- if node_id_or_hostname_list:
- # Separate the list into integers and strings
- node_ids = filter(lambda node_id: isinstance(node_id, (int, long)),
- node_id_or_hostname_list)
- hostnames = filter(lambda hostname: isinstance(hostname, StringTypes),
- node_id_or_hostname_list)
- sql += " AND (False"
- if node_ids:
- sql += " OR node_id IN (%s)" % ", ".join(map(str, node_ids))
- if hostnames:
- sql += " OR hostname IN (%s)" % ", ".join(api.db.quote(hostnames)).lower()
- sql += ")"
-
- # So that if the node has a primary interface, it is listed
- # first.
- if 'nodenetwork_ids' in extra_fields:
- sql += " ORDER BY node_nodenetworks.is_primary DESC"
-
- rows = self.api.db.selectall(sql)
- for row in rows:
- if self.has_key(row['node_id']):
- node = self[row['node_id']]
- node.update(row)
- else:
- self[row['node_id']] = Node(api, row)
-
- # XXX Should instead have a site_node join table that is
- # magically taken care of above.
- if rows:
- sql = "SELECT node_id, sites.site_id FROM nodegroup_nodes" \
- " INNER JOIN sites USING (nodegroup_id)" \
- " WHERE node_id IN (%s)" % ", ".join(map(str, self.keys()))
-
- rows = self.api.db.selectall(sql, self)
- for row in rows:
- assert self.has_key(row['node_id'])
- node = self[row['node_id']]
- node.update(row)
-
- # Fill in optional primary interface fields for each node
- if extra_nodenetwork_fields:
- # More efficient to get all the nodenetworks at once
- nodenetwork_ids = []
- for node in self.values():
- nodenetwork_ids += node['nodenetwork_ids']