{ "info": { "author": "Alex Plugaru", "author_email": "alex@plugaru.org", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "\n# kuku\n\n[![Build Status](https://travis-ci.org/xarg/kuku.svg?branch=master)](https://travis-ci.org/xarg/kuku)\n\nkuku renders kubernetes yaml manifests using python templates. It is similar to [helm](https://helm.sh/) in usage (templates dir, value files, etc..).\n\n\n## Installation:\n\n```bash\npip3 install kuku\n```\n\nor using the docker image:\n\n```bash\ndocker pull xarg/kuku\n\n# Example usage (see more below):\ndocker run -v $(pwd)/:/tmp/ --rm xarg/kuku render -f /tmp/your-values.yaml /tmp/your-templates/ | kubectl apply -\n```\n\n## Usage\n\nSuppose you want to create a k8s service using a template where you define the service `name`, `internalPort` and `externalPort`.\n\nGiven the following `service.py` template:\n```python\nfrom kubernetes import client\n\n\ndef template(context):\n return client.V1Service(\n api_version=\"v1\",\n kind=\"Service\",\n metadata=client.V1ObjectMeta(name=context[\"name\"]),\n spec=client.V1ServiceSpec(\n type=\"NodePort\",\n ports=[\n {\"port\": context[\"externalPort\"], \"targetPort\": context[\"internalPort\"]}\n ],\n selector={\"app\": context[\"name\"]},\n ),\n )\n```\n\nYou can now generate a yaml output from the above template using `kuku` by running: \n```bash\n$ ls .\nservice.py \n$ kuku render -s name=kuku-web,internalPort=80,externalPort=80 .\n```\nthe above produces:\n```yaml\n# Source: service.py\napiVersion: v1\nkind: Service\nmetadata:\n name: kuku-web\nspec:\n ports:\n - port: 80\n targetPort: 80\n selector:\n app: kuku-web\n type: NodePort\n```\n\n\nYou can also combine the above with `kubectl apply -f -` to actually create your service on k8s:\n```bash\nkuku render -s name=kuku-web,internalPort=80,externalPort=80 . | kubectl apply -f -\n```\n\nSame as above, but let's make it shorter:\n```bash\nkuku apply -s name=kuku-web,internalPort=80,externalPort=80 .\n```\n\n\nFinally to delete it: \n```bash\nkuku delete -s name=kuku-web,internalPort=80,externalPort=80 .\n# same as above\nkuku render -s name=kuku-web,internalPort=80,externalPort=80 . | kubectl delete -f - \n```\n\n## Templates \n\nTemplates are python files that are defining a function called `template` that accepts a dict argument `context` and \nreturns a k8s object or a list of k8s objects:\n\n```python\ndef template(context):\n return V1Namespace(name=context['namespace']) # example k8s object \n```\n\nYou can create multiple template files each defining their own `template` function.\n`kuku` uses the k8s objects (aka models) from [official kubernetes python client package](https://github.com/kubernetes-client/python).\nYou can find them all [here](https://github.com/kubernetes-client/python/blob/master/kubernetes/README.md#documentation-for-models)\n\n\n## CLI\n\nSimilar to [helm](https://helm.sh/) `kuku` accepts defining it's context variables from the CLI:\n\n```bash\nkuku -s namespace=kuku .\n```\n\n`-s namespace=kuku` will be passed to the `context` argument in your `template` function. Run `kuku -h` to find out more.\n\n## Goals\n\n#### Write python code to generate k8s manifests.\nPython is a very popular language with a huge ecosystem of devops packages. Most importantly it's easier to debug than \nsome templating languages used today to generate k8s manifests.\n\n#### No k8s server side dependencies (i.e. tiller).\nk8s already has a database for it's current state (using etcd). We can connect directly to it from the client to \ndo our operations instead of relying on an extra server side dependency.\n\n#### Local validation of manifests before running `kubectl apply`. \nWhere possible do the validation locally using the [official k8s python client](https://github.com/kubernetes-client/python).\n\n#### Use standard tools\nWhere possible use `kubectl` to apply changes to the k8s cluster instead of implementing a specific protocol.\nAgain, this will make debugging easier for the end user.\n\n## Why not helm?\n\nAt [Gorgias](https://gorgias.io) we use [helm](https://helm.sh/) to manage our infrastructure, but there are a few \nthings that we found problematic with it:\n\n- Poor templating language: requires constant referral to the docs, whitespace issues, yaml formatting is hard.\n- Server side dependency: if you upgrade the server -> every user needs to update their client - waste of valuable time.\n- Lack of local validation: `helm lint` does not really ensure the validity (i.e. required keys for a k8s object) of the manifest.\n\nChart names, releases and other helm specific features do not really fit with our current workflow.\n\n\n# Contributing\n\nContributions (code, issues, docs, etc..) are welcome!\n\nOnce you have your python environment setup:\n\n```bash\npip install -e .[dev] # will install dev dependencies\npre-commit install # will install pre-commit hooks for code quality checking \n```\n\nPublish a new version to pypi:\n```bash\npython setup.py upload\n```\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/xarg/kuku", "keywords": "", "license": "Apache", "maintainer": "", "maintainer_email": "", "name": "kuku", "package_url": "https://pypi.org/project/kuku/", "platform": "", "project_url": "https://pypi.org/project/kuku/", "project_urls": { "Homepage": "https://github.com/xarg/kuku" }, "release_url": "https://pypi.org/project/kuku/0.1.1/", "requires_dist": [ "docopt", "PyYAML", "requests", "kubernetes", "twine; extra == 'dev'", "wheel; extra == 'dev'", "pytest; extra == 'dev'", "pytest-cov; extra == 'dev'", "black; extra == 'dev'", "mypy; extra == 'dev'", "pre-commit; extra == 'dev'" ], "requires_python": ">=3.5.0", "summary": "Kubernetes templating tool.", "version": "0.1.1" }, "last_serial": 5744771, "releases": { "0.0.2": [ { "comment_text": "", "digests": { "md5": "8b0184008ffb038f8d5a8c6d9de0508f", "sha256": "168aba3e04b7d068e47b07d4979d08fa8a57497442cdda60ae3bd574ba3098b1" }, "downloads": -1, "filename": "kuku-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8b0184008ffb038f8d5a8c6d9de0508f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.5.0", "size": 11941, "upload_time": "2018-09-27T18:04:40", "url": "https://files.pythonhosted.org/packages/e9/ac/d0244097c6b1efbd10ea5b89471902c58aadfcfd7f4720e68b6fd55e4368/kuku-0.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dda034a7ea2c1f2544d71b66d99e7abc", "sha256": "f7fa2abed75f10ac5d585e4b8ceaef61c4ec6c227f4d4acbca275ff1dfb7699d" }, "downloads": -1, "filename": "kuku-0.0.2.tar.gz", "has_sig": false, "md5_digest": "dda034a7ea2c1f2544d71b66d99e7abc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 10863, "upload_time": "2018-09-27T18:04:41", "url": "https://files.pythonhosted.org/packages/1a/7f/44b8024600ab3d39233a56f56aaecdb96f76db20080ecee9e88be3742574/kuku-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "9b5cfbe1a719f19e115edccaed0e3e94", "sha256": "fbb44e23a85184fbcba07614edad9c450aef505ca3c2058aff41c8c21a3fdca2" }, "downloads": -1, "filename": "kuku-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9b5cfbe1a719f19e115edccaed0e3e94", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.5.0", "size": 12307, "upload_time": "2018-09-27T20:54:48", "url": "https://files.pythonhosted.org/packages/a0/21/9c343a7f735c23fb7c21128b908d1a18417b0bb57a23ce7b02103974e576/kuku-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "28bd4e8452d9ede68a0a0904561ba084", "sha256": "783c5e0d777bcd3a72aa5cf274f082496ec91a4ce1fdcee1e55270df3a2a258e" }, "downloads": -1, "filename": "kuku-0.0.3.tar.gz", "has_sig": false, "md5_digest": "28bd4e8452d9ede68a0a0904561ba084", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 11078, "upload_time": "2018-09-27T20:54:49", "url": "https://files.pythonhosted.org/packages/c6/32/7c5bc84dd857b225f87883959430272c60490d979dbd2f6ab082a1d4d6c4/kuku-0.0.3.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "3e2ccaa2aa63ed713d70640bf594ff30", "sha256": "5df3104b5cd6b5e38a7c9d1ae0764459901633fce1006058cfeb4a0169630c7d" }, "downloads": -1, "filename": "kuku-0.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3e2ccaa2aa63ed713d70640bf594ff30", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.5.0", "size": 16418, "upload_time": "2018-11-19T23:00:07", "url": "https://files.pythonhosted.org/packages/f2/20/78b76ebeeaf970a1fe6bfdf5853125caaf67497246f177461022b3c75b8c/kuku-0.0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1b1ddbf8be31d795e29f24e171f7f1b6", "sha256": "22956a28dd46a7a6c7837d6674d3b5c8e84329ac4b0ec1592dd5092f6b396233" }, "downloads": -1, "filename": "kuku-0.0.5.tar.gz", "has_sig": false, "md5_digest": "1b1ddbf8be31d795e29f24e171f7f1b6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 10926, "upload_time": "2018-11-19T23:00:09", "url": "https://files.pythonhosted.org/packages/18/28/0077ec7183a21ae0985312a6cb5d92f06084f22ea52738420b1469dfb49c/kuku-0.0.5.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "3b75dc788d2a04b7dfa3e4adabe47dfc", "sha256": "827149db0b36e03b1bf5838149fcc218b9f0ccc443829f2b601ef6fa4a94814d" }, "downloads": -1, "filename": "kuku-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3b75dc788d2a04b7dfa3e4adabe47dfc", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.5.0", "size": 16775, "upload_time": "2019-08-28T19:06:30", "url": "https://files.pythonhosted.org/packages/46/b9/80c2994edb8fe3369a03a351471f07ec054684ddaee92af0339061123d62/kuku-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8f5741edb25b6d5be882123df910b7a9", "sha256": "75ee598c55ed3fff017aaa0699549ce45b04296ec30d0ff82fe5ff7f7ca2dafa" }, "downloads": -1, "filename": "kuku-0.1.1.tar.gz", "has_sig": false, "md5_digest": "8f5741edb25b6d5be882123df910b7a9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 11332, "upload_time": "2019-08-28T19:06:32", "url": "https://files.pythonhosted.org/packages/21/b9/9dfd0d977628cb59cc5bb9d6bfa712df06a9f99bc4239c446320416b5f14/kuku-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3b75dc788d2a04b7dfa3e4adabe47dfc", "sha256": "827149db0b36e03b1bf5838149fcc218b9f0ccc443829f2b601ef6fa4a94814d" }, "downloads": -1, "filename": "kuku-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3b75dc788d2a04b7dfa3e4adabe47dfc", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.5.0", "size": 16775, "upload_time": "2019-08-28T19:06:30", "url": "https://files.pythonhosted.org/packages/46/b9/80c2994edb8fe3369a03a351471f07ec054684ddaee92af0339061123d62/kuku-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8f5741edb25b6d5be882123df910b7a9", "sha256": "75ee598c55ed3fff017aaa0699549ce45b04296ec30d0ff82fe5ff7f7ca2dafa" }, "downloads": -1, "filename": "kuku-0.1.1.tar.gz", "has_sig": false, "md5_digest": "8f5741edb25b6d5be882123df910b7a9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5.0", "size": 11332, "upload_time": "2019-08-28T19:06:32", "url": "https://files.pythonhosted.org/packages/21/b9/9dfd0d977628cb59cc5bb9d6bfa712df06a9f99bc4239c446320416b5f14/kuku-0.1.1.tar.gz" } ] }