Set new grains values in the grains config file

    destructive
        If an operation results in a key being removed, delete the key, too.
        Defaults to False.

    CLI Example:

    .. code-block:: bash

        salt '*' grains.setvals "{'key1': 'val1', 'key2': 'val2'}"

def setvals(grains, destructive=False):
    '''
    Set new grains values in the grains config file

    destructive
        If an operation results in a key being removed, delete the key, too.
        Defaults to False.

    CLI Example:

    .. code-block:: bash

        salt '*' grains.setvals "{'key1': 'val1', 'key2': 'val2'}"
    '''
    new_grains = grains
    if not isinstance(new_grains, collections.Mapping):
        raise SaltException('setvals grains must be a dictionary.')
    grains = {}
    if os.path.isfile(__opts__['conf_file']):
        if salt.utils.platform.is_proxy():
            gfn = os.path.join(
                os.path.dirname(__opts__['conf_file']),
                'proxy.d',
                __opts__['id'],
                'grains'
            )
        else:
            gfn = os.path.join(
                os.path.dirname(__opts__['conf_file']),
                'grains'
            )
    elif os.path.isdir(__opts__['conf_file']):
        if salt.utils.platform.is_proxy():
            gfn = os.path.join(
                __opts__['conf_file'],
                'proxy.d',
                __opts__['id'],
                'grains'
            )
        else:
            gfn = os.path.join(
                __opts__['conf_file'],
                'grains'
            )
    else:
        if salt.utils.platform.is_proxy():
            gfn = os.path.join(
                os.path.dirname(__opts__['conf_file']),
                'proxy.d',
                __opts__['id'],
                'grains'
            )
        else:
            gfn = os.path.join(
                os.path.dirname(__opts__['conf_file']),
                'grains'
            )

    if os.path.isfile(gfn):
        with salt.utils.files.fopen(gfn, 'rb') as fp_:
            try:
                grains = salt.utils.yaml.safe_load(fp_)
            except salt.utils.yaml.YAMLError as exc:
                return 'Unable to read existing grains file: {0}'.format(exc)
        if not isinstance(grains, dict):
            grains = {}
    for key, val in six.iteritems(new_grains):
        if val is None and destructive is True:
            if key in grains:
                del grains[key]
            if key in __grains__:
                del __grains__[key]
        else:
            grains[key] = val
            __grains__[key] = val
    try:
        with salt.utils.files.fopen(gfn, 'w+') as fp_:
            salt.utils.yaml.safe_dump(grains, fp_, default_flow_style=False)
    except (IOError, OSError):
        log.error(
            'Unable to write to grains file at %s. Check permissions.',
            gfn
        )
    fn_ = os.path.join(__opts__['cachedir'], 'module_refresh')
    try:
        with salt.utils.files.flopen(fn_, 'w+'):
            pass
    except (IOError, OSError):
        log.error(
            'Unable to write to cache file %s. Check permissions.',
            fn_
        )
    if not __opts__.get('local', False):
        # Refresh the grains
        __salt__['saltutil.refresh_grains']()
    # Return the grains we just set to confirm everything was OK
    return new_grains