.. versionadded:: 2016.3.0

    Create k8s secrets in the defined namespace from the list of files

    CLI Example:

    .. code-block:: bash

        salt '*' k8s.create_secret namespace_name secret_name sources

        salt '*' k8s.create_secret namespace_name secret_name sources
        http://kube-master.cluster.local

    sources are either dictionary of {name: path, name1: path} pairs or array of strings defining paths.

    Example of paths array:

    .. code-block:: bash

    ['/full/path/filename', "file:///full/path/filename", "salt://secret/storage/file.txt", "http://user:password@securesite.com/secret-file.json"]

    Example of dictionaries:

    .. code-block:: bash

    {"nameit": '/full/path/fiename', name2: "salt://secret/storage/file.txt"}

    optional parameters accepted:

    update=[false] default value is false
    if set to false, and secret is already present on the cluster - warning will be returned and no changes to the secret will be done.
    In case it is set to "true" and secret is present but data is differ - secret will be updated.

    force=[true] default value is true
    if the to False, secret will not be created in case one of the files is not
    valid kubernetes secret. e.g. capital letters in secret name or _
    in case force is set to True, wrong files will be skipped but secret will be created any way.

    saltenv=['base'] default value is base
    in case 'salt://' path is used, this parameter can change the visibility of files

def create_secret(namespace, name, sources, apiserver_url=None, force=False, update=False, saltenv='base'):
    '''
    .. versionadded:: 2016.3.0

    Create k8s secrets in the defined namespace from the list of files

    CLI Example:

    .. code-block:: bash

        salt '*' k8s.create_secret namespace_name secret_name sources

        salt '*' k8s.create_secret namespace_name secret_name sources
        http://kube-master.cluster.local

    sources are either dictionary of {name: path, name1: path} pairs or array of strings defining paths.

    Example of paths array:

    .. code-block:: bash

    ['/full/path/filename', "file:///full/path/filename", "salt://secret/storage/file.txt", "http://user:password@securesite.com/secret-file.json"]

    Example of dictionaries:

    .. code-block:: bash

    {"nameit": '/full/path/fiename', name2: "salt://secret/storage/file.txt"}

    optional parameters accepted:

    update=[false] default value is false
    if set to false, and secret is already present on the cluster - warning will be returned and no changes to the secret will be done.
    In case it is set to "true" and secret is present but data is differ - secret will be updated.

    force=[true] default value is true
    if the to False, secret will not be created in case one of the files is not
    valid kubernetes secret. e.g. capital letters in secret name or _
    in case force is set to True, wrong files will be skipped but secret will be created any way.

    saltenv=['base'] default value is base
    in case 'salt://' path is used, this parameter can change the visibility of files

    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}

    if not sources:
        return {'name': name, 'result': False, 'comment': 'No source available', 'changes': {}}

    apiserver_url = _guess_apiserver(apiserver_url)
    # we need namespace to create secret in it
    if not _get_namespaces(apiserver_url, namespace):
        if force:
            _create_namespace(namespace, apiserver_url)
        else:
            return {'name': name, 'result': False, 'comment': "Namespace doesn't exists", 'changes': {}}

    secret = _get_secrets(namespace, name, apiserver_url)
    if secret and not update:
        log.info("Secret %s is already present on %s", name, namespace)
        return {'name': name, 'result': False,
                'comment': 'Secret {0} is already present'.format(name),
                'changes': {}}

    data = {}

    for source in sources:
        log.debug("source is: %s", source)
        if isinstance(source, dict):
            # format is array of dictionaries:
            # [{public_auth: salt://public_key}, {test: "/tmp/test"}]
            log.trace("source is dictionary: %s", source)
            for k, v in six.iteritems(source):
                sname, encoded = _source_encode(v, saltenv)
                if sname == encoded == "":
                    ret['comment'] += "Source file {0} is missing or name is incorrect\n".format(v)
                    if force:
                        continue
                    else:
                        return ret
                data[k] = encoded
        elif isinstance(source, six.string_types):
            # expected format is array of filenames
            sname, encoded = _source_encode(source, saltenv)
            if sname == encoded == "":
                if force:
                    ret['comment'] += "Source file {0} is missing or name is incorrect\n".format(source)
                    continue
                else:
                    return ret
            data[sname] = encoded

    log.trace('secret data is: %s', data)

    if secret and update:
        if not data:
            ret["comment"] += "Could not find source files or your sources are empty"
            ret["result"] = False
        elif secret.get("data") and data != secret.get("data"):
            res = _update_secret(namespace, name, data, apiserver_url)
            ret['comment'] = 'Updated secret'
            ret['changes'] = 'Updated secret'
        else:
            log.debug("Secret has not been changed on cluster, skipping it")
            ret['comment'] = 'Has not been changed on cluster, skipping it'
    else:
        res = _create_secret(namespace, name, data, apiserver_url)
    return ret