'Given an iterable of IP addresses identifying a storage backend server,
return a set of all bind ports defined in all rings for this storage
backend server.
The caller is responsible for not calling this method (which performs
at least a stat on all ring files) too frequently.'

def all_bind_ports_for_node(self):

    for policy in POLICIES:
        serialized_path = os.path.join(self.swift_dir, (policy.ring_name + '.ring.gz'))
        try:
            new_mtime = os.path.getmtime(serialized_path)
        except OSError:
            continue
        old_mtime = self.mtimes_by_ring_path.get(serialized_path)
        if ((not old_mtime) or (old_mtime != new_mtime)):
            self.portsets_by_ring_path[serialized_path] = set((dev['port'] for dev in RingData.load(serialized_path, metadata_only=True).devs if (dev and (dev['ip'] in self.my_ips))))
            self.mtimes_by_ring_path[serialized_path] = new_mtime
    return six.moves.reduce(set.union, self.portsets_by_ring_path.values(), set())
