def present(name,
            base_dashboards_from_pillar=None,
            base_panels_from_pillar=None,
            base_rows_from_pillar=None,
            dashboard=None,
            profile='grafana'):
    '''
    Ensure the grafana dashboard exists and is managed.

    name
        Name of the grafana dashboard.

    base_dashboards_from_pillar
        A pillar key that contains a list of dashboards to inherit from

    base_panels_from_pillar
        A pillar key that contains a list of panels to inherit from

    base_rows_from_pillar
        A pillar key that contains a list of rows to inherit from

    dashboard
        A dict that defines a dashboard that should be managed.

    profile
        A pillar key or dict that contains grafana information
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}

    base_dashboards_from_pillar = base_dashboards_from_pillar or []
    base_panels_from_pillar = base_panels_from_pillar or []
    base_rows_from_pillar = base_rows_from_pillar or []
    dashboard = dashboard or {}

    if isinstance(profile, six.string_types):
        profile = __salt__['config.option'](profile)

    # Add pillar keys for default configuration
    base_dashboards_from_pillar = ([_DEFAULT_DASHBOARD_PILLAR] +
                                   base_dashboards_from_pillar)
    base_panels_from_pillar = ([_DEFAULT_PANEL_PILLAR] +
                               base_panels_from_pillar)
    base_rows_from_pillar = [_DEFAULT_ROW_PILLAR] + base_rows_from_pillar

    # Build out all dashboard fields
    new_dashboard = _inherited_dashboard(
        dashboard, base_dashboards_from_pillar, ret)
    new_dashboard['title'] = name
    rows = new_dashboard.get('rows', [])
    for i, row in enumerate(rows):
        rows[i] = _inherited_row(row, base_rows_from_pillar, ret)
    for row in rows:
        panels = row.get('panels', [])
        for i, panel in enumerate(panels):
            panels[i] = _inherited_panel(panel, base_panels_from_pillar, ret)
    _auto_adjust_panel_spans(new_dashboard)
    _ensure_panel_ids(new_dashboard)
    _ensure_annotations(new_dashboard)

    # Create dashboard if it does not exist
    url = 'db/{0}'.format(name)
    old_dashboard = _get(url, profile)
    if not old_dashboard:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = 'Dashboard {0} is set to be created.'.format(name)
            return ret

        response = _update(new_dashboard, profile)
        if response.get('status') == 'success':
            ret['comment'] = 'Dashboard {0} created.'.format(name)
            ret['changes']['new'] = 'Dashboard {0} created.'.format(name)
        else:
            ret['result'] = False
            ret['comment'] = ("Failed to create dashboard {0}, "
                              "response={1}").format(name, response)
        return ret

    # Add unmanaged rows to the dashboard. They appear at the top if they are
    # marked as pinned. They appear at the bottom otherwise.
    managed_row_titles = [row.get('title')
                          for row in new_dashboard.get('rows', [])]
    new_rows = new_dashboard.get('rows', [])
    for old_row in old_dashboard.get('rows', []):
        if old_row.get('title') not in managed_row_titles:
            new_rows.append(copy.deepcopy(old_row))
    _ensure_pinned_rows(new_dashboard)
    _ensure_panel_ids(new_dashboard)

    # Update dashboard if it differs
    dashboard_diff = DictDiffer(_cleaned(new_dashboard),
                                _cleaned(old_dashboard))
    updated_needed = (dashboard_diff.changed() or
                      dashboard_diff.added() or
                      dashboard_diff.removed())
    if updated_needed:
        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = (
                str('Dashboard {0} is set to be updated, changes={1}').format(  # future lint: blacklisted-function
                    name,
                    salt.utils.json.dumps(
                        _dashboard_diff(
                            _cleaned(new_dashboard),
                            _cleaned(old_dashboard)
                        ),
                        indent=4
                    )
                )
            )
            return ret

        response = _update(new_dashboard, profile)
        if response.get('status') == 'success':
            updated_dashboard = _get(url, profile)
            dashboard_diff = DictDiffer(_cleaned(updated_dashboard),
                                        _cleaned(old_dashboard))
            ret['comment'] = 'Dashboard {0} updated.'.format(name)
            ret['changes'] = _dashboard_diff(_cleaned(new_dashboard),
                                             _cleaned(old_dashboard))
        else:
            ret['result'] = False
            ret['comment'] = ("Failed to update dashboard {0}, "
                              "response={1}").format(name, response)
        return ret

    ret['comment'] = 'Dashboard present'
    return ret