'Ensures project_tree has quotas that make sense as nested quotas.
Validates the following:
* No parent project has child_projects who have more combined quota
than the parent\'s quota limit
* No child quota has a larger in-use value than it\'s current limit
(could happen before because child default values weren\'t enforced)
* All parent projects\' "allocated" quotas match the sum of the limits
of its children projects
TODO(mc_nair): need a better way to "flip the switch" to use nested
quotas to make this less race-ee'

def validate_nested_setup(self, ctxt, resources, project_tree, fix_allocated_quotas=False):

    self._allocated = {}
    project_queue = deque(project_tree.items())
    borked_allocated_quotas = {}
    while project_queue:
        (cur_proj_id, project_subtree) = project_queue.popleft()
        if (not project_subtree):
            continue
        cur_project_quotas = self.get_project_quotas(ctxt, resources, cur_proj_id)
        for resource in cur_project_quotas.keys():
            parent_quota = cur_project_quotas[resource]
            parent_limit = parent_quota['limit']
            parent_usage = (parent_quota['in_use'] + parent_quota['reserved'])
            cur_parent_allocated = parent_quota.get('allocated', 0)
            calc_parent_allocated = self._get_cur_project_allocated(ctxt, resources[resource], {cur_proj_id: project_subtree})
            if (parent_limit > 0):
                parent_free_quota = (parent_limit - parent_usage)
                if (parent_free_quota < calc_parent_allocated):
                    msg = (_("Sum    of    child    usage    '%(sum)s'    is    greater    than    free    quota    of    '%(free)s'    for    project    '%(proj)s'    for    resource    '%(res)s'.    Please    lower    the    limit    or    usage    for    one    or    more    of    the    following    projects:    '%(child_ids)s'") % {'sum': calc_parent_allocated, 'free': parent_free_quota, 'proj': cur_proj_id, 'res': resource, 'child_ids': ',    '.join(project_subtree.keys())})
                    raise exception.InvalidNestedQuotaSetup(reason=msg)
            if (calc_parent_allocated != cur_parent_allocated):
                if fix_allocated_quotas:
                    try:
                        db.quota_allocated_update(ctxt, cur_proj_id, resource, calc_parent_allocated)
                    except exception.ProjectQuotaNotFound:
                        db.quota_create(ctxt, cur_proj_id, resource, parent_limit, allocated=calc_parent_allocated)
                else:
                    if (cur_proj_id not in borked_allocated_quotas):
                        borked_allocated_quotas[cur_proj_id] = {}
                    borked_allocated_quotas[cur_proj_id][resource] = {'db_allocated_quota': cur_parent_allocated, 'expected_allocated_quota': calc_parent_allocated}
        project_queue.extend(project_subtree.items())
    if borked_allocated_quotas:
        msg = (_('Invalid    allocated    quotas    defined    for    the    following    project    quotas:    %s') % borked_allocated_quotas)
        raise exception.InvalidNestedQuotaSetup(message=msg)
