plainconf


Nameplainconf JSON
Version 0.1.20 PyPI version JSON
download
home_page
SummaryMinimal configuration handling supporting hashicorp vault.
upload_time2023-09-25 07:46:05
maintainer
docs_urlNone
author
requires_python
license
keywords configuration vault
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Plainconf

Attempts to help build sensible configuration for python projects.

## DISCLAIMER

Unless you need some specific functionality in here, 
I recommend using [Dynaconf](https://www.dynaconf.com/) as it is more mature.


## Install 

```shell
pip install plainconf
```


## What does this do?

It will create a flat conf (no nesting or anything, just one level) 
taking entries from the same environment from
a settings file and either

 * a secrets file

 * hashicorp vault if vault_url, a mount_point and either token, 
   userpass or approle credentials are provided (optionally vault_path)
 
 * a secrets file with fernet encrypted values if the key is provided 
   (s. [encrypting toml file with fernet](#markdown-header-encrypting-toml-file-with-fernet)


settings.toml
``` toml
[development]
db_url = "localhost:4321"
```


.secrets.toml
``` toml
[development]
password = "secret"
``` 


``` python
    conf = Plainconf(
        environment="development",
        settings_file="settings.toml",
        secrets_file=".secrets.toml",
    )

    assert conf.db_url == "localhost:4321"
    assert conf.password == "secret"

``` 

## Assumptions

Plainconf assumes, that the setings and secrets are organised in envrironments.
Further it assumes, that the relevant configuration is the most specific one and
all levels above hold common information for the levels below.

``` toml
[development]
...                   <- this information is relevant to development.local

[development.local]   <- this is the environment you want to work with (including everything from development)
...


[development.staging]
...
``` 

## Encrypting toml file with fernet

In order to encrypt the values in the toml file you will need a fernet key

``` python
    from cyptography.fernet import Fernet

    key = Fernet.generate_key()
```

encrypt_toml(key: bytes, file: str) expects the key as bytes and the path to the secrets file to
be encrypted:

``` python
    from plainconf import encrypt_toml

    encrypt_toml(b'key', '.secrets.toml')
```
Which will output a file ending on \_enc.toml with the values encrypted

``` toml
[development]
password = "gAAAAABlDfsMIkZzIqKFQW8NBHVIqITKLCgQkzr6VKOYglHroZ--jFtkEsFr3feqSL1WCWy7gdlhvjHkBmx_JjQxKYKiqNge0A=="
```

In order to read the encrypted secrets, the key has to be given as 
keyword argument or environment variable (without the b at the beginning)

## Nested environments

Plainconf will read the environment given in the variable and the entries
above and flatten everything, as that is the use case I have.

``` toml
[development]
db_url = "localhost:4321"

[development.local]
db_username = "local"
```

``` python
conf = Plainconf(
    environment="development.local",
    settings_file="settings.toml",
)

assert conf.db_url == "localhost:4321"
assert conf.db_username == "local"
```


## Limitations

* Only supports userpass, approle and token authentication on Hashicorp Vault

* Only works with kv secret engine

* Only supports toml

(for now)


## Examples

With files

``` toml
    .mysecrets.toml:

    [development]
    password = 'secret'
```

``` python
    conf = Plainconf(
        secrets_file='.mysecrets.toml', 
        settings_file='mysettings.toml',
        environment='development'
    )
    
    ...

    conf.password ("secret")
```
 

With vault

    on the vault:
    
    somewhere/development:
    password = 'supersecret'


``` python
    conf = Plainconf(
        vault_url="http://localhost:8200",
        vault_token="hvs.abc123def456",
        vault_mount_point="somewhere",
        environment="development"
    )

    conf.password ("supersecret")
```


Enviroment from env

    .env file:

    PLAINCONF_ENVIRONMENT="development"
    PLAINCONF_VAULT_TOKEN="hvs.something123"
    PLAINCONF_VAULT_URL="http://development.vault:8200"

``` python
    conf = Plainconf()
    conf.password ("supersecret")
```
 
### Settings REQUIRED!

    Plainconf(settings_file='path_to_file')
    or environment variable PLAINCONF_SETTINGS_FILE="...""

Settings are read from the respective environment (default: default)

### Secrets 

    Plainconf(secrets_file='path_to_file')
    or environment variable PLAINCONF_SECRETS_FILE="...""

Secrets are read from the environment (default: default)

### Environments

    Plainconf(environment='name')
    or environment variable PLAINCONF_ENVIRONMENT="...""
    or default: default

### Vault

Hashicorp Vault can be accessed via token, approle or userpass.

Required configuration:

* Plainconf(vault_url='http...') 
  or environment variable PLAINCONF_VAULT_URL

* Plainconf(vault_mount_point='name')
  or environment variable PLAINCONF_VAULT_MOUNT_POINT

and either a token 

* Plainconf(vault_token="hvs...") 
  or PLAINCONF_VAULT_TOKEN

or user and pass

* Plainconf(vault_user='user', vault_pass='password') 
  or PLAINCONF_VAULT_USER and PLAINCONF_VAULT_PASS

or approle id and secret

* Plainconf(vault_approle_id='role_id', vault_approle_secret_id='secret_id')
  or PLAINCONF_APPROLE_ID and PLAINCONF_APPROLE_SECRET_ID

Optional:

* Plainconf(vault_path='secret/special...')
  or PLAINCONF_VAULT_PATH
  or default: environment (see above)

Plainconf tries to connect to the vault kv secrets engine v2 by default 
and v1 thereafter.


## Fernet Key

* Plainconf(fernet_key='key')
  or PLAINCONF_FERNET_KEY'

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "plainconf",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "configuration,vault",
    "author": "",
    "author_email": "Caspar David Dzikus <caspar@kodekitchen.com>",
    "download_url": "https://files.pythonhosted.org/packages/9e/9b/f48e757b912ad395f24f940a9d5b80b36a139fa56f3b348f9c64cf44bbc7/plainconf-0.1.20.tar.gz",
    "platform": null,
    "description": "# Plainconf\n\nAttempts to help build sensible configuration for python projects.\n\n## DISCLAIMER\n\nUnless you need some specific functionality in here, \nI recommend using [Dynaconf](https://www.dynaconf.com/) as it is more mature.\n\n\n## Install \n\n```shell\npip install plainconf\n```\n\n\n## What does this do?\n\nIt will create a flat conf (no nesting or anything, just one level) \ntaking entries from the same environment from\na settings file and either\n\n * a secrets file\n\n * hashicorp vault if vault_url, a mount_point and either token, \n   userpass or approle credentials are provided (optionally vault_path)\n \n * a secrets file with fernet encrypted values if the key is provided \n   (s. [encrypting toml file with fernet](#markdown-header-encrypting-toml-file-with-fernet)\n\n\nsettings.toml\n``` toml\n[development]\ndb_url = \"localhost:4321\"\n```\n\n\n.secrets.toml\n``` toml\n[development]\npassword = \"secret\"\n``` \n\n\n``` python\n    conf = Plainconf(\n        environment=\"development\",\n        settings_file=\"settings.toml\",\n        secrets_file=\".secrets.toml\",\n    )\n\n    assert conf.db_url == \"localhost:4321\"\n    assert conf.password == \"secret\"\n\n``` \n\n## Assumptions\n\nPlainconf assumes, that the setings and secrets are organised in envrironments.\nFurther it assumes, that the relevant configuration is the most specific one and\nall levels above hold common information for the levels below.\n\n``` toml\n[development]\n...                   <- this information is relevant to development.local\n\n[development.local]   <- this is the environment you want to work with (including everything from development)\n...\n\n\n[development.staging]\n...\n``` \n\n## Encrypting toml file with fernet\n\nIn order to encrypt the values in the toml file you will need a fernet key\n\n``` python\n    from cyptography.fernet import Fernet\n\n    key = Fernet.generate_key()\n```\n\nencrypt_toml(key: bytes, file: str) expects the key as bytes and the path to the secrets file to\nbe encrypted:\n\n``` python\n    from plainconf import encrypt_toml\n\n    encrypt_toml(b'key', '.secrets.toml')\n```\nWhich will output a file ending on \\_enc.toml with the values encrypted\n\n``` toml\n[development]\npassword = \"gAAAAABlDfsMIkZzIqKFQW8NBHVIqITKLCgQkzr6VKOYglHroZ--jFtkEsFr3feqSL1WCWy7gdlhvjHkBmx_JjQxKYKiqNge0A==\"\n```\n\nIn order to read the encrypted secrets, the key has to be given as \nkeyword argument or environment variable (without the b at the beginning)\n\n## Nested environments\n\nPlainconf will read the environment given in the variable and the entries\nabove and flatten everything, as that is the use case I have.\n\n``` toml\n[development]\ndb_url = \"localhost:4321\"\n\n[development.local]\ndb_username = \"local\"\n```\n\n``` python\nconf = Plainconf(\n    environment=\"development.local\",\n    settings_file=\"settings.toml\",\n)\n\nassert conf.db_url == \"localhost:4321\"\nassert conf.db_username == \"local\"\n```\n\n\n## Limitations\n\n* Only supports userpass, approle and token authentication on Hashicorp Vault\n\n* Only works with kv secret engine\n\n* Only supports toml\n\n(for now)\n\n\n## Examples\n\nWith files\n\n``` toml\n    .mysecrets.toml:\n\n    [development]\n    password = 'secret'\n```\n\n``` python\n    conf = Plainconf(\n        secrets_file='.mysecrets.toml', \n        settings_file='mysettings.toml',\n        environment='development'\n    )\n    \n    ...\n\n    conf.password (\"secret\")\n```\n \n\nWith vault\n\n    on the vault:\n    \n    somewhere/development:\n    password = 'supersecret'\n\n\n``` python\n    conf = Plainconf(\n        vault_url=\"http://localhost:8200\",\n        vault_token=\"hvs.abc123def456\",\n        vault_mount_point=\"somewhere\",\n        environment=\"development\"\n    )\n\n    conf.password (\"supersecret\")\n```\n\n\nEnviroment from env\n\n    .env file:\n\n    PLAINCONF_ENVIRONMENT=\"development\"\n    PLAINCONF_VAULT_TOKEN=\"hvs.something123\"\n    PLAINCONF_VAULT_URL=\"http://development.vault:8200\"\n\n``` python\n    conf = Plainconf()\n    conf.password (\"supersecret\")\n```\n \n### Settings REQUIRED!\n\n    Plainconf(settings_file='path_to_file')\n    or environment variable PLAINCONF_SETTINGS_FILE=\"...\"\"\n\nSettings are read from the respective environment (default: default)\n\n### Secrets \n\n    Plainconf(secrets_file='path_to_file')\n    or environment variable PLAINCONF_SECRETS_FILE=\"...\"\"\n\nSecrets are read from the environment (default: default)\n\n### Environments\n\n    Plainconf(environment='name')\n    or environment variable PLAINCONF_ENVIRONMENT=\"...\"\"\n    or default: default\n\n### Vault\n\nHashicorp Vault can be accessed via token, approle or userpass.\n\nRequired configuration:\n\n* Plainconf(vault_url='http...') \n  or environment variable PLAINCONF_VAULT_URL\n\n* Plainconf(vault_mount_point='name')\n  or environment variable PLAINCONF_VAULT_MOUNT_POINT\n\nand either a token \n\n* Plainconf(vault_token=\"hvs...\") \n  or PLAINCONF_VAULT_TOKEN\n\nor user and pass\n\n* Plainconf(vault_user='user', vault_pass='password') \n  or PLAINCONF_VAULT_USER and PLAINCONF_VAULT_PASS\n\nor approle id and secret\n\n* Plainconf(vault_approle_id='role_id', vault_approle_secret_id='secret_id')\n  or PLAINCONF_APPROLE_ID and PLAINCONF_APPROLE_SECRET_ID\n\nOptional:\n\n* Plainconf(vault_path='secret/special...')\n  or PLAINCONF_VAULT_PATH\n  or default: environment (see above)\n\nPlainconf tries to connect to the vault kv secrets engine v2 by default \nand v1 thereafter.\n\n\n## Fernet Key\n\n* Plainconf(fernet_key='key')\n  or PLAINCONF_FERNET_KEY'\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Minimal configuration handling supporting hashicorp vault.",
    "version": "0.1.20",
    "project_urls": {
        "bugtracker": "https://github.com/kodekitchen/plainconf/issues",
        "repository": "https://github.com/kodekitchen/plainconf"
    },
    "split_keywords": [
        "configuration",
        "vault"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "33e267ab10cdacb20531ee98e03f80d49624d0593731a74c25a91d5b617fa8a7",
                "md5": "dd5829608f356bbbbe039551d54bae29",
                "sha256": "3e203708a13eefc12128146b34bab3842d3d5a4663f1a9b9522d63bf63f7690f"
            },
            "downloads": -1,
            "filename": "plainconf-0.1.20-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "dd5829608f356bbbbe039551d54bae29",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 5854,
            "upload_time": "2023-09-25T07:46:02",
            "upload_time_iso_8601": "2023-09-25T07:46:02.571542Z",
            "url": "https://files.pythonhosted.org/packages/33/e2/67ab10cdacb20531ee98e03f80d49624d0593731a74c25a91d5b617fa8a7/plainconf-0.1.20-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9e9bf48e757b912ad395f24f940a9d5b80b36a139fa56f3b348f9c64cf44bbc7",
                "md5": "ce9be8da22fc99a3d49bcc09e9b62c90",
                "sha256": "12897e9a8daef995bb40552748eed794c0d0c2de5b5b35b1f375234ba47a1fa0"
            },
            "downloads": -1,
            "filename": "plainconf-0.1.20.tar.gz",
            "has_sig": false,
            "md5_digest": "ce9be8da22fc99a3d49bcc09e9b62c90",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 5994,
            "upload_time": "2023-09-25T07:46:05",
            "upload_time_iso_8601": "2023-09-25T07:46:05.617217Z",
            "url": "https://files.pythonhosted.org/packages/9e/9b/f48e757b912ad395f24f940a9d5b80b36a139fa56f3b348f9c64cf44bbc7/plainconf-0.1.20.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-09-25 07:46:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "kodekitchen",
    "github_project": "plainconf",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "plainconf"
}
        
Elapsed time: 0.66036s