'Return a list of nodes in the current zone or all zones.
:keyword  ex_zone:  Optional zone name or \'all\'
:type     ex_zone:  ``str`` or :class:`GCEZone` or
:class:`NodeLocation` or ``None``
:keyword  ex_use_disk_cache:  Disk information for each node will
retrieved from a dictionary rather
than making a distinct API call for it.
:type     ex_use_disk_cache: ``bool``
:return:  List of Node objects
:rtype:   ``list`` of :class:`Node`'

def list_nodes(self, ex_zone=None, ex_use_disk_cache=True):

    list_nodes = []
    zone = self._set_zone(ex_zone)
    if (zone is None):
        request = '/aggregated/instances'
    else:
        request = ('/zones/%s/instances' % zone.name)
    response = self.connection.request(request, method='GET').object
    if ('items' in response):
        if (zone is None):
            self._ex_populate_volume_dict()
            for v in response['items'].values():
                for i in v.get('instances', []):
                    try:
                        list_nodes.append(self._to_node(i, use_disk_cache=ex_use_disk_cache))
                    except ResourceNotFoundError:
                        pass
        else:
            for i in response['items']:
                try:
                    list_nodes.append(self._to_node(i, use_disk_cache=ex_use_disk_cache))
                except ResourceNotFoundError:
                    pass
    self._ex_volume_dict = {}
    return list_nodes
