{ "info": { "author": "Michael Persson", "author_email": "michael.ake.persson@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: System Administrators", "License :: OSI Approved :: Apache Software License", "Operating System :: POSIX :: Linux" ], "description": "Pepa\n====\n\nConfiguration templating for SaltStack using Hierarchical substitution and Jinja.\n\n.. image:: https://drone.io/github.com/mickep76/pepa/status.png\n :alt: drone.io build status\n :target: https://drone.io/github.com/mickep76/pepa\n\nPepa is part of the SaltStack as of release 2014.7.\n\nQuick testing\n=============\n\nYou can easily test Pepa from the Command Line.\n\nCreate a virtual env. and install the required modules.\n\n.. code-block:: bash\n\n virtualenv venv\n cd venv\n source bin/activate\n pip install pepa\n\nClone and run Pepa.\n\n.. code-block:: bash\n\n git clone https://github.com/mickep76/pepa.git\n cd pepa\n pepa -c examples/master test.example.com -d\n\nTest and validate templates.\n\n.. code-block:: bash\n\n pepa-test --config examples/master -d\n\nLook at output.\n\n.. code-block:: bash\n\n pepa-test --config examples/master -d -s\n\nInstall Pepa\n============\n\n.. code-block:: bash\n\n git clone https://github.com/mickep76/pepa.git\n mkdir -p /srv/salt/ext/pillar\n cp pillar/pepa.py /srv/salt/ext/pillar/pepa.py\n\nConfiguring Pepa\n================\n\n.. code-block:: yaml\n\n extension_modules: /srv/salt/ext\n\n ext_pillar:\n - pepa:\n resource: host # Name of resource directory and sub-key in pillars\n sequence: # Sequence used for hierarchical substitution\n - hostname: # Name of key\n name: input # Alias used for template directory\n base_only: True # Only use templates from Base environment, i.e. no staging\n - default:\n - environment:\n - location..region:\n name: region\n - location..country:\n name: country\n - location..datacenter:\n name: datacenter\n - roles:\n - osfinger:\n name: os\n - hostname:\n name: override\n base_only: True\n subkey: True # Create a sub-key in pillars, named after the resource in this case [host]\n subkey_only: True # Only create a sub-key, and leave the top level untouched\n\n pepa_roots: # Base directory for each environment\n base: /srv/pepa/base # Path for base environment\n dev: /srv/pepa/base # Associate dev with base\n qa: /srv/pepa/qa\n prod: /srv/pepa/prod\n\n # Use a different delimiter for nested dictionaries, defaults to '..' since some keys may use '.' in the name\n #pepa_delimiter: ..\n\n # Supply Grains for Pepa, this should **ONLY** be used for testing or validation\n #pepa_grains:\n # environment: dev\n\n # Supply Pillar for Pepa, this should **ONLY** be used for testing or validation\n #pepa_pillars:\n # saltversion: 0.17.4\n\n # Enable debug for Pepa, and keep Salt on warning\n #log_level: debug\n\n #log_granular_levels:\n # salt: warning\n # salt.loaded.ext.pillar.pepa: debug\n\nPepa can also be used in Master-less SaltStack setup.\n\nCommand line\n============\n\n.. code-block:: bash\n\n usage: pepa [-h] [-c CONFIG] [-d] [-g GRAINS] [-p PILLAR] [-n] [-v]\n hostname\n\n positional arguments:\n hostname Hostname\n\n optional arguments:\n -h, --help show this help message and exit\n -c CONFIG, --config CONFIG\n Configuration file\n -r RESOURCE, --resource RESOURCE\n Resource, defaults to first resource\n -d, --debug Print debug info\n -g GRAINS, --grains GRAINS\n Input Grains as YAML\n -p PILLAR, --pillar PILLAR\n Input Pillar as YAML\n -n, --no-color No color output\n -v, --validate Validate output\n\nTemplates\n=========\n\nTemplates is configuration for a host or software, that can use information from Grains or Pillars. These can then be used for hierarchically substitution.\n\n**Example File:** host/input/test_example_com.yaml\n\n.. code-block:: yaml\n\n location..region: emea\n location..country: nl\n location..datacenter: foobar\n environment: dev\n roles:\n - salt.master\n network..gateway: 10.0.0.254\n network..interfaces..eth0..hwaddr: 00:20:26:a1:12:12\n network..interfaces..eth0..dhcp: False\n network..interfaces..eth0..ipv4: 10.0.0.3\n network..interfaces..eth0..netmask: 255.255.255.0\n network..interfaces..eth0..fqdn: {{ hostname }}\n cobbler..profile: fedora-19-x86_64\n\nAs you see in this example you can use Jinja directly inside the template.\n\n**Example File:** host/region/amer.yaml\n\n.. code-block:: yaml\n\n network..dns..servers:\n - 10.0.0.1\n - 10.0.0.2\n time..ntp..servers:\n - ntp1.amer.example.com\n - ntp2.amer.example.com\n - ntp3.amer.example.com\n time..timezone: America/Chihuahua\n yum..mirror: yum.amer.example.com\n\nEach template is named after the value of the key using lowercase and all extended characters are replaced with underscore.\n\n**Example:**\n\nosfinger: Fedora-19\n\n**Would become:**\n\nfedora_19.yaml\n\nNested dictionaries\n===================\n\nIn order to create nested dictionaries as output you can use double dot **\"..\"** as a delimiter. You can change this using \"pepa_delimiter\" we choose double dot since single dot is already used by key names in some modules, and using \":\" requires quoting in the YAML.\n\n**Example:**\n\n.. code-block:: yaml\n\n network..dns..servers:\n - 10.0.0.1\n - 10.0.0.2\n network..dns..options:\n - timeout:2\n - attempts:1\n - ndots:1\n network..dns..search:\n - example.com\n\n**Would become:**\n\n.. code-block:: yaml\n\n network:\n dns:\n servers:\n - 10.0.0.1\n - 10.0.0.2\n options:\n - timeout:2\n - attempts:1\n - ndots:1\n search:\n - example.com\n\nOperators\n=========\n\nOperators can be used to merge/unset a list/hash or set the key as immutable, so it can't be changed.\n\n=========== ================================================\nOperator Description\n=========== ================================================\nmerge() Merge list or hash\nunset() Unset key\nimmutable() Set the key as immutable, so it can't be changed\nimerge() Set immutable and merge\niunset() Set immutable and unset\n=========== ================================================\n\n**Example:**\n\n.. code-block:: yaml\n\n network..dns..search..merge():\n - foobar.com\n - dummy.nl\n owner..immutable(): Operations\n host..printers..unset():\n\nTesting\n=======\n\nPepa also come's with a test/validation tool for templates. This allows you to test for valid Jinja/YAML and validate key values.\n\nCommand Line\n============\n\n.. code-block:: bash\n\n usage: pepa-test [-h] [-c CONFIG] [-r RESOURCE] [-d] [-s] [-t] [-n]\n\n optional arguments:\n -h, --help show this help message and exit\n -c CONFIG, --config CONFIG\n Configuration file\n -r RESOURCE, --resource RESOURCE\n Configuration file, defaults to first resource\n -d, --debug Print debug info\n -s, --show Show result of template\n -t, --teamcity Output validation in TeamCity format\n -n, --no-color No color output\n\nTest\n====\n\nA test is a set of input values for a template, it's generally a good idea to create a separate test for each outcome if you have Jinja if statements.\n\n**Example:** host/default/tests/default-1.yaml\n\n.. code-block:: yaml\n\n grains..osfinger: Fedora-20\n location..region: emea\n\nYou can also use Jinja inside a test, for example if you wan't to iterate through test values.\n\nSchema\n======\n\nA schema is a set of validation rules for each key/value. Schemas use `Cerberus `_ module for validation.\n\n**Example:** host/schemas/pkgrepo.yaml\n\n.. code-block:: yaml\n\n {% set hostname = '^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-zA-Z]{2,6}$' %}\n {% set url = '(http|https?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?)' %}\n\n pkgrepo..mirror:\n type: string\n regex: {{ hostname }}\n\n pkgrepo..type:\n type: string\n allowed: yum\n\n pkgrepo..osabbr:\n type: string\n regex: ^(fc|rhel)[0-9]+$\n\n {% for repo in [ 'base', 'everything', 'updates' ] %}\n pkgrepo..repos..{{ repo }}..name:\n type: string\n regex: ^[A-Za-z\\ 0-9\\-\\_]+$\n\n pkgrepo..repos..{{ repo }}..baseurl:\n type: string\n regex: {{ url }}\n {% endfor %}\n\nYou can also use Jinja inside a schema, for example if you wan't to iterate through a list of different keys.\n\nYou can create complicated datastructures underneth a key, but it's advisable to split it in several\nkeys using the delimiter for a nested data structures.\n\n**Bad**\n\n.. code-block:: yaml\n\n network:\n interfaces:\n eth0:\n ipv4: 192.168.1.2\n netmask: 255.255.255.0\n\n**Good**\n\n.. code-block:: yaml\n\n network..interfaces..eth0..ipv4: 192.168.1.2\n network..interfaces..eth0..netmask: 255.255.255.0\n\nThe first example you can't properly use substitution and defining the schema becomes more complicated.", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/mickep76/pepa.git", "keywords": "", "license": "Apache License, Version 2.0", "maintainer": "", "maintainer_email": "", "name": "pepa", "package_url": "https://pypi.org/project/pepa/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/pepa/", "project_urls": { "Homepage": "https://github.com/mickep76/pepa.git" }, "release_url": "https://pypi.org/project/pepa/0.8.1/", "requires_dist": null, "requires_python": "", "summary": "Configuration templating for SaltStack using Hierarchical substitution and Jinja", "version": "0.8.1" }, "last_serial": 2504814, "releases": { "0.7.0": [], "0.7.1": [ { "comment_text": "", "digests": { "md5": "b36098fe7c3f9e1debb98fbc3ee12e36", "sha256": "044dedfa132a50c4bb07bb2735f9c96c369f1dd5206dcc8359b5416c1a124484" }, "downloads": -1, "filename": "pepa-0.7.1.tar.gz", "has_sig": false, "md5_digest": "b36098fe7c3f9e1debb98fbc3ee12e36", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7567, "upload_time": "2014-10-10T13:19:26", "url": "https://files.pythonhosted.org/packages/7a/2e/976ec75c88aabd725883a470e5eaf776407b3276822d9020847fcbf3d73f/pepa-0.7.1.tar.gz" } ], "0.7.2": [ { "comment_text": "", "digests": { "md5": "7451dde4e026701279857272124a41f6", "sha256": "699b81f971060265f687b051d71ccb4dd508e516044856ad41b1c9016459f839" }, "downloads": -1, "filename": "pepa-0.7.2.tar.gz", "has_sig": false, "md5_digest": "7451dde4e026701279857272124a41f6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7874, "upload_time": "2014-10-13T13:00:42", "url": "https://files.pythonhosted.org/packages/bd/3d/28ca4b5bbd3e15655fde7031c7653c4620852baebda3aac897c2fb1ebf62/pepa-0.7.2.tar.gz" } ], "0.7.3": [ { "comment_text": "", "digests": { "md5": "0991f2f70a66222766f60dd797fb5f4d", "sha256": "6fa1179c7b1dbb0446cb91015bef6a97206ca8d665a102d593c01f118574de50" }, "downloads": -1, "filename": "pepa-0.7.3.tar.gz", "has_sig": false, "md5_digest": "0991f2f70a66222766f60dd797fb5f4d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8914, "upload_time": "2014-10-13T14:46:16", "url": "https://files.pythonhosted.org/packages/68/b2/e7a996dbffc7677374187a98b1bbd7da77d02b2a0a78f553e168a08c8cc6/pepa-0.7.3.tar.gz" } ], "0.7.4": [ { "comment_text": "", "digests": { "md5": "0b7b829f6cdc736bfcf0b7da54f297d0", "sha256": "8a7f4fe8f6a37fb6f802b179c14a20510f510b1ce64e25fbdc4f2570ccf194cc" }, "downloads": -1, "filename": "pepa-0.7.4.tar.gz", "has_sig": false, "md5_digest": "0b7b829f6cdc736bfcf0b7da54f297d0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9458, "upload_time": "2014-10-13T16:13:04", "url": "https://files.pythonhosted.org/packages/06/c4/6b8a4449d29d0bc2bd1449b2123ccce53a1b4269de525cb40b1c43c2514b/pepa-0.7.4.tar.gz" } ], "0.7.5": [ { "comment_text": "", "digests": { "md5": "654ff13f4e0c6c0ee6e4872a2a10c02b", "sha256": "82b3beaa543d9bcd43d498c21ca7e6019d53e5830df6aae126cc301326426c8f" }, "downloads": -1, "filename": "pepa-0.7.5.tar.gz", "has_sig": false, "md5_digest": "654ff13f4e0c6c0ee6e4872a2a10c02b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9454, "upload_time": "2014-10-13T16:14:54", "url": "https://files.pythonhosted.org/packages/37/8b/fe72336eddfba1b5425dc5b7ab80374891729043773c01be2f2c15912f65/pepa-0.7.5.tar.gz" } ], "0.7.6": [ { "comment_text": "", "digests": { "md5": "c0375976a71e6a0116a5145ce04f408e", "sha256": "3c30d2c0acb2c945c7ff7981e4f96f520e246e05e71026d4c78c73b712309813" }, "downloads": -1, "filename": "pepa-0.7.6.tar.gz", "has_sig": false, "md5_digest": "c0375976a71e6a0116a5145ce04f408e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10983, "upload_time": "2014-10-24T15:15:22", "url": "https://files.pythonhosted.org/packages/60/4f/144520f2954e8a0e05921b9dc0d766f66cd802a9424b9f7a0c89c825e653/pepa-0.7.6.tar.gz" } ], "0.7.7": [ { "comment_text": "", "digests": { "md5": "e14b871aa56bf439762258b8a570611f", "sha256": "abb5e18005618401630b02de48308f00736df152b67094552c2d47c201dfbd5e" }, "downloads": -1, "filename": "pepa-0.7.7.tar.gz", "has_sig": false, "md5_digest": "e14b871aa56bf439762258b8a570611f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9363, "upload_time": "2014-10-24T15:23:37", "url": "https://files.pythonhosted.org/packages/12/7b/0ed2b4256c5a56e64328405d45f8a52f5052e777181694739a2b8e4aa2bc/pepa-0.7.7.tar.gz" } ], "0.7.8": [ { "comment_text": "", "digests": { "md5": "d3f113f71cb006e50e1143de80e19ba8", "sha256": "7814717137969bb4accfe2157b64f987ef3610d5a02b1580d77f476e90d9d618" }, "downloads": -1, "filename": "pepa-0.7.8.tar.gz", "has_sig": false, "md5_digest": "d3f113f71cb006e50e1143de80e19ba8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9392, "upload_time": "2014-10-24T15:26:53", "url": "https://files.pythonhosted.org/packages/5d/7f/e25c9385c1d150f4f5867942dbdbeb35fc5f42790070ebb749289ebf797a/pepa-0.7.8.tar.gz" } ], "0.7.9": [ { "comment_text": "", "digests": { "md5": "201ecf1ddde3d26efdebe4a6bba8e35e", "sha256": "b86a33cfc8b97cc7e76e53b0643164d945ab2798c925cf203ee0ccfbbc8fb4c8" }, "downloads": -1, "filename": "pepa-0.7.9.tar.gz", "has_sig": false, "md5_digest": "201ecf1ddde3d26efdebe4a6bba8e35e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9434, "upload_time": "2014-10-24T15:50:14", "url": "https://files.pythonhosted.org/packages/66/10/b40bbc3f7e30303f6f0a02f077a8a321762c043157cc885a8df9706c9592/pepa-0.7.9.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "1de12728d4e53b6ee4522683c0495ae7", "sha256": "e52c9d35f3df4a85899a62bcab3d94e1626aa3f308c39213fb92c5c99c4fdaa8" }, "downloads": -1, "filename": "pepa-0.8.0.tar.gz", "has_sig": false, "md5_digest": "1de12728d4e53b6ee4522683c0495ae7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9416, "upload_time": "2016-12-06T17:13:15", "url": "https://files.pythonhosted.org/packages/b4/4b/be6e2957285440b02721f033bf0f7fc659178ba74663aea04ad424c46029/pepa-0.8.0.tar.gz" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "606fe4708b7023a47ad91ffa99241a8f", "sha256": "a67775a8e79aad61fa2e9edd423377fb87c7385b36531d03d72867f359898966" }, "downloads": -1, "filename": "pepa-0.8.1.tar.gz", "has_sig": false, "md5_digest": "606fe4708b7023a47ad91ffa99241a8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9315, "upload_time": "2016-12-07T14:50:19", "url": "https://files.pythonhosted.org/packages/a7/5b/4a7150818321284041d00518dbd0df80036e189ca74ad77e21a5c76fa4f7/pepa-0.8.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "606fe4708b7023a47ad91ffa99241a8f", "sha256": "a67775a8e79aad61fa2e9edd423377fb87c7385b36531d03d72867f359898966" }, "downloads": -1, "filename": "pepa-0.8.1.tar.gz", "has_sig": false, "md5_digest": "606fe4708b7023a47ad91ffa99241a8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9315, "upload_time": "2016-12-07T14:50:19", "url": "https://files.pythonhosted.org/packages/a7/5b/4a7150818321284041d00518dbd0df80036e189ca74ad77e21a5c76fa4f7/pepa-0.8.1.tar.gz" } ] }