{ "info": { "author": "Daniel Milde", "author_email": "daniel.milde@firma.seznam.cz", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python :: 3" ], "description": "\n\n# Vindaloo\n[![Build Status](https://travis-ci.org/seznam/vindaloo.svg?branch=master)](https://travis-ci.org/seznam/vindaloo)\n[![codecov](https://codecov.io/gh/seznam/vindaloo/branch/master/graph/badge.svg)](https://codecov.io/gh/seznam/vindaloo)\n\n`Vindaloo` is universal deployer into kubernetes. It easily provides one project to work with multiple docker registries, repositories, kubernetes clusters and namespaces without the need of duplicating configuration.\n\nRequirements\n------------\n\nPython 3.5 and higher is required.\n\n\nInstallation\n------------\n\nDownload latest [pex binary](https://github.com/seznam/vindaloo/raw/master/latest/vindaloo.pex)\n\n```\nsudo wget -O /usr/bin/vindaloo https://github.com/seznam/vindaloo/raw/master/latest/vindaloo.pex\nsudo chmod +x /usr/bin/vindaloo\n```\n\nor use pip:\n\n```\npip3 install vindaloo\n```\n\nWhat can it do\n--------------\n\n- build docker images\n- push to docker registry\n- deploy to k8s\n- check versions in k8s\n- edit k8s secrets\n- bash completion\n\nWhy to use Vindaloo and not X\n-----------------------------\n\n- can be distributed as one executable file, no need to install\n- configuration using Python files which implies little code duplication and huge expressivity\n- powerful templating using Mustache language (pystache)\n- can include parts of templates in Dockerfiles\n- can build multiple images from one component\n- can change docker context dir for building an image\n- high test coverage\n- can bash-complete options, environments and images used in the component\n\nConfiguration\n-------------\n\n`Vindaloo` uses two levels of configuration.\n\n\"Global\" configuration is expected to be placed in `vindaloo_conf.py` and\ndefines a list of environments, corresponding k8s namespaces and k8s clusters.\n`vindaloo_conf.py` can be placed into the directory of the deployed component or\nany parent directory, e.g. into your home folder if you share the same k8s environment (namespaces, clusters)\nfor all your projects.\n\nEvery project/component/service using `Vindaloo` must have directory `k8s`,\nwhich contains configuration for build and deployment of this component.\n`Vindaloo` generates deployments, Dockerfiles, etc. and calls `kubectl` and `docker` using this configuration.\n\n\nTypical usage\n-------------\n\n```\ncd projekt\nvindaloo init .\n\nvindaloo build\nvindaloo push\nvindaloo deploy dev cluster1\nvindaloo deploy dev cluster2\n\nvindaloo versions\n```\n\nBash completion\n---------------\n\nAdd this to your `~/.bashrc` to enable bash completion:\n\n```\nsource <(vindaloo completion)\n```\n\n\nComponent configuration\n-----------------------\n\n```\nvindaloo_conf.py\nk8s\n templates\n - Dockerfile\n - deployment.yaml\n - service.yaml\n\n - base.py\n - dev.py\n - test.py\n - stable.py\n - versions.json\n```\n\n`vindaloo_conf.py` contains the definition of deployment environments (dev, test, prerelease, stable), corresponding k8s namespaces and list of k8s clusters.\nThe file can be placed in the directory of the component or in any parent dir (if we share the configuration among more components).\n\nConfiguration of the component's deployment is placed in the `k8s` directory, where a couple of files is located:\n\n`templates` contains templates of generated files (yamls, Dockerfiles).\nThey use mustache syntax, which provides simple loops etc.\nSyntax: https://mustache.github.io/mustache.5.html\n\n`base.py` is the basis of configuration and should contain everything, what will have all the environment configurations in common.\n\n`[dev/test/...].py` are config files for individual k8s environments and contain settings specific for them (e.g. nodePort).\n\n`versions.json` is a configuration file defining versions of images we want to build/deploy.\nWe can easily read and modify it programmatically because it's valid JSON.\n\n\nExample vindaloo_conf.py\n------------------------\n\n```\nENVS = {\n 'dev': {\n 'k8s_namespace': 'avengers-dev',\n 'k8s_clusters': ['cluster1', 'cluster2'],\n 'docker_registry': 'foo-registry.com',\n },\n 'test': {\n 'k8s_namespace': 'avengers-test',\n 'k8s_clusters': ['cluster1', 'cluster2'],\n 'docker_registry': 'foo-registry.com',\n },\n 'staging': {\n 'k8s_namespace': 'avengers-staging',\n 'k8s_clusters': ['cluster1', 'cluster2'],\n 'docker_registry': 'foo-registry.com',\n },\n 'stable': {\n 'k8s_namespace': 'avengers-stable',\n 'k8s_clusters': ['cluster1', 'cluster2'],\n 'docker_registry': 'foo-registry.com',\n },\n}\n\nK8S_CLUSTER_ALIASES = {\n 'c1': 'cluster1',\n 'c2': 'cluster2',\n}\n```\n\n\nExample base.py\n---------------\n\n```\n# import image versions from versions.json as a dict (awfull hack)\nimport versions\n\n# will be used further\nCONFIG = {\n 'maintainer': \"John Doe \",\n 'version': versions['avengers/cool_app'],\n 'image_name': 'avengers/cool_app',\n}\n\n# will be used further\nDEPLOYMENT = {\n 'replicas': 2,\n 'ident_label': \"cool-app\",\n 'image': \"{}:{}\".format(CONFIG['image_name'], CONFIG['version']),\n 'container_port': 6666,\n 'env': [\n {\n 'key': 'BACKEND',\n 'val': \"some-url.com\"\n },\n ]\n}\n\n# will be used further\nSERVICE = {\n 'app_name': \"cool-app\",\n 'ident_label': \"cool-app\",\n 'container_port': 6666,\n 'port': 31666,\n}\n\n# Dockerfiles configuration\n# list of dicts with keys:\n# config - dict with configuration\n# template - file with Dockerfile template\n# context_dir - directory passed to docker (optional)\n# pre_build_msg - message shown before the build is started (optional)\n# includes - loading of files to be included into Dockerfile.\nEvery file will be processed with mustache with same context as main template.\n\nDOCKER_FILES = [\n {\n 'context_dir': \".\",\n 'config': CONFIG,\n 'template': \"Dockerfile\",\n 'pre_build_msg': \"\"\"Please run first:\n\nmake clean\n\"\"\"\n 'includes': {\n 'some_name': 'path/to/file/with/template',\n }\n }\n]\n\n# K8S configuration\nK8S_OBJECTS = {\n \"deployment\": [\n {\n 'config': DEPLOYMENT,\n 'template': \"deployment.yaml\",\n },\n ],\n \"service\": [\n {\n 'config': SERVICE,\n 'template': \"service.yaml\",\n },\n ]\n}\n```\n\nExample dev.py\n--------------\n\n```\nfrom base import * # config inheritance\n\n# Here we can overload or modify everything what was defined in base.py\n\n\nDEPLOYMENT.update({\n 'env': [\n {\n 'key': 'BACKEND',\n 'val': \"some-other-url.com\"\n },\n ]\n})\n\nSERVICE.update({\n 'port': 32666,\n})\n```\n\nExample versions.json\n---------------------\n\n```\n{\n \"avengers/cool_app\": \"1.0.0\"\n}\n```\n\n\nExample Dockerfile\n------------------\n\n```\n{{#includes}}{{&base_image}}{{/includes}}\nLABEL maintainer=\"{{{maintainer}}}\"\nLABEL description=\"Avengers cool app\"\n\nCOPY ...\nRUN ...\nCMD ...\n\nLABEL version=\"{{version}}\"\n```\n\nExample deployment.yaml\n-----------------------\n\n```\napiVersion: extensions/v1beta1\nkind: Deployment\nmetadata:\n name: {{ident_label}}\nspec:\n replicas: {{replicas}}\n template:\n metadata:\n name: {{ident_label}}\n labels:\n app: {{ident_label}}\n spec:\n containers:\n - name: {{ident_label}}\n image: {{registry}}/{{image}}\n ports:\n - containerPort: {{container_port}}\n livenessProbe:\n initialDelaySeconds: 5\n periodSeconds: 5\n httpGet:\n path: /\n port: {{container_port}}\n```\n\nExample service.yaml\n--------------------\n\n```\napiVersion: v1\nkind: Service\nmetadata:\n name: {{ident_label}}\n labels:\n name: {{ident_label}}\nspec:\n type: NodePort\n ports:\n - name: http\n nodePort: {{port}}\n port: {{container_port}}\n protocol: TCP\n selector:\n app: {{app_name}}\n```\n\nAdvanced configuration\n---------------------------\n\nConfiguration written in Python allows us to solve a far more complicated scenarios.\n\nWe can build more images from one component and the deploy them into one pod.\nSee the [example](examples/multi-image/k8s).\n\nWe can create python module similar to crontab and generate CronJobs dynamically using it.\nThen if we need to run some task out of schedule, we can deploy one k8s Job by passing ENV variable for example.\n\n```\nDEPLOY_JOB=campaign-run-manager vindaloo deploy dev\n```\n\nSee the [example](examples/cron-jobs/k8s).\n\nExperimental configuration using classes\n----------------------------------------\n\nKubernetes manifests can be configured using dicts (classical way) or classes (experimental).\nThis feature is not considered stable yet and should be used with caution.\nThe advantage is that base configuration can be more easily changed in environment config files.\n\nThe data structure used in classes is basically the same as in K8S JSON manifests with some exceptions.\nAll `name`, `value` lists used in K8S (i.e. `env`) are stored as `key`: `value` python dicts.\n\nSee the [example](examples/class-config/k8s).\n\nHow to build `vindaloo`\n-----------------------\n\n```\npip install pystache pex\n\nmake\n\n# success\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/seznam/vindaloo", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "vindaloo", "package_url": "https://pypi.org/project/vindaloo/", "platform": "", "project_url": "https://pypi.org/project/vindaloo/", "project_urls": { "Homepage": "https://github.com/seznam/vindaloo" }, "release_url": "https://pypi.org/project/vindaloo/3.1.1/", "requires_dist": [ "argcomplete (>=1.9.5)", "pystache", "typing" ], "requires_python": ">=3.5", "summary": "K8S deployer", "version": "3.1.1" }, "last_serial": 5873213, "releases": { "2.2.0": [ { "comment_text": "", "digests": { "md5": "db1a4ea139843a42f5b6df56e6e41837", "sha256": "4b64c6601767a3c02aff49ea9427117aef6867e36b03bdd0a5494c4cce3bef02" }, "downloads": -1, "filename": "vindaloo-2.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "db1a4ea139843a42f5b6df56e6e41837", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14619, "upload_time": "2019-09-05T09:02:19", "url": "https://files.pythonhosted.org/packages/be/cc/c1677f81e7f106fa370c38f360f81d98b6d7613e9aeee2be090b15c8af28/vindaloo-2.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c7f4b4608dd3ad5670bb81afb45ae0d5", "sha256": "bdda8e25098c2da5cb6b23341e4470fb9796cc73f34e0301eddf947d9270acac" }, "downloads": -1, "filename": "vindaloo-2.2.0.tar.gz", "has_sig": false, "md5_digest": "c7f4b4608dd3ad5670bb81afb45ae0d5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16228, "upload_time": "2019-09-05T09:02:22", "url": "https://files.pythonhosted.org/packages/bc/c4/05885c117042d61498de7a2e500572cf3eba601d8dc0a52ab6483b1e5fa3/vindaloo-2.2.0.tar.gz" } ], "3.0.0": [ { "comment_text": "", "digests": { "md5": "a34e619ee355f5384503e7c06eb27592", "sha256": "b5cd151efceedd3a105fbc98eeec0f71b273ceb4765040a2a7f40ee847c69212" }, "downloads": -1, "filename": "vindaloo-3.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "a34e619ee355f5384503e7c06eb27592", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15219, "upload_time": "2019-09-13T08:36:45", "url": "https://files.pythonhosted.org/packages/c3/fd/08db09e24111707ac73e1285b1826276c2daf8f2f8ccca74b9c8110341d6/vindaloo-3.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8f0791f451861664cf286b1fd94526c9", "sha256": "af413c70933405e4cfdc5e3307fd751cc2fc24740e7743e26eca800bdd2fae7e" }, "downloads": -1, "filename": "vindaloo-3.0.0.tar.gz", "has_sig": false, "md5_digest": "8f0791f451861664cf286b1fd94526c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16027, "upload_time": "2019-09-13T08:36:48", "url": "https://files.pythonhosted.org/packages/06/fa/76e815cef80eb47e590790ed19da10e4d265e40b7109f667c7c51fd4d194/vindaloo-3.0.0.tar.gz" } ], "3.0.1": [ { "comment_text": "", "digests": { "md5": "b7878d1596df82d2a0290f9064c0c580", "sha256": "21394d7b50d0832a9fee9041de2e3ae5338d327724c8fbe076a96fbd6e11f612" }, "downloads": -1, "filename": "vindaloo-3.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b7878d1596df82d2a0290f9064c0c580", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18480, "upload_time": "2019-09-13T08:48:42", "url": "https://files.pythonhosted.org/packages/99/0c/0ba7b4d9c24f5fa9fecd4e72941fa7661f1753bb21cbde643e25a1eed261/vindaloo-3.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2019116d17f6df4b1bbaf1ce9c7e41d2", "sha256": "0e6cd9a7cea989e1c58fd5bbe8d02f90ffdd8e505ad64b5b324e389d8fd892a4" }, "downloads": -1, "filename": "vindaloo-3.0.1.tar.gz", "has_sig": false, "md5_digest": "2019116d17f6df4b1bbaf1ce9c7e41d2", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 20335, "upload_time": "2019-09-13T08:48:44", "url": "https://files.pythonhosted.org/packages/b6/6d/476f646e800650835019bc8806e1dec491b32d620a17c126782da10ee3d2/vindaloo-3.0.1.tar.gz" } ], "3.0.2": [ { "comment_text": "", "digests": { "md5": "2b9503abb1df618e899dd67f77e95984", "sha256": "e3ddcfaa9d9c1551d3cd9e03f77bfb7f02820c9e3cd104455a1cdee571d2f960" }, "downloads": -1, "filename": "vindaloo-3.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "2b9503abb1df618e899dd67f77e95984", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18500, "upload_time": "2019-09-13T13:53:31", "url": "https://files.pythonhosted.org/packages/54/99/d52bf084c0b6ae5016c13eeabf664a822242c4e4d0bfda6060b00319af71/vindaloo-3.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eb517f21591452bf0e42d8298a6c35a6", "sha256": "945e5840f7b168cf0e3b3db0ccdd82f2fa04d68a9181047f7be78fa5692f765e" }, "downloads": -1, "filename": "vindaloo-3.0.2.tar.gz", "has_sig": false, "md5_digest": "eb517f21591452bf0e42d8298a6c35a6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 20353, "upload_time": "2019-09-13T13:53:34", "url": "https://files.pythonhosted.org/packages/c5/6e/eb3dccac9bf3465ca08af2df0ba23dedfd28187e7ed57a0319bf82fd5048/vindaloo-3.0.2.tar.gz" } ], "3.1.0": [ { "comment_text": "", "digests": { "md5": "35620ff880d2c2c3c49f4ac14560364e", "sha256": "a342defdef1f2fcc16b5fe3545e922a4dc97ec35d0fee55c9ce77221cba91437" }, "downloads": -1, "filename": "vindaloo-3.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "35620ff880d2c2c3c49f4ac14560364e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18501, "upload_time": "2019-09-13T14:19:44", "url": "https://files.pythonhosted.org/packages/77/2a/11215a60a16495279c1f55cfb9395647e4ec03b1307d9586261bb1530ba9/vindaloo-3.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1a840f843c02733c8f0bea5d382131e5", "sha256": "7dcf502c0669f20ec26e2cddaa169b51b6d64f6291cde52b26838df2535d7066" }, "downloads": -1, "filename": "vindaloo-3.1.0.tar.gz", "has_sig": false, "md5_digest": "1a840f843c02733c8f0bea5d382131e5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 20361, "upload_time": "2019-09-13T14:19:48", "url": "https://files.pythonhosted.org/packages/75/26/740b8912be439b7c7d6d28013089b94db72e2a08d06c9e85131d66207df3/vindaloo-3.1.0.tar.gz" } ], "3.1.1": [ { "comment_text": "", "digests": { "md5": "1a1238524b6fa2936f2d3ed37e738f18", "sha256": "1e72a1639c00ae73fa7e4bd6a85a550d524472b3cda2b548350af64c9e903286" }, "downloads": -1, "filename": "vindaloo-3.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1a1238524b6fa2936f2d3ed37e738f18", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18501, "upload_time": "2019-09-23T12:05:53", "url": "https://files.pythonhosted.org/packages/e8/11/29f2fda00f81216b6625a615ab2b10b307950a4c9a0d26f0a14bf07bc73c/vindaloo-3.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92735785ff16a6135f67c1d9f741ad17", "sha256": "203fc6001262f4c67a7ba85bcd8ffc326b739f33dfeb4e2fca20ab4d632f18d9" }, "downloads": -1, "filename": "vindaloo-3.1.1.tar.gz", "has_sig": false, "md5_digest": "92735785ff16a6135f67c1d9f741ad17", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 20364, "upload_time": "2019-09-23T12:05:59", "url": "https://files.pythonhosted.org/packages/1d/6d/bf577330e5151becc5b0cadf358fa63ba45f78db6dc412751bfe77610cc7/vindaloo-3.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1a1238524b6fa2936f2d3ed37e738f18", "sha256": "1e72a1639c00ae73fa7e4bd6a85a550d524472b3cda2b548350af64c9e903286" }, "downloads": -1, "filename": "vindaloo-3.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "1a1238524b6fa2936f2d3ed37e738f18", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 18501, "upload_time": "2019-09-23T12:05:53", "url": "https://files.pythonhosted.org/packages/e8/11/29f2fda00f81216b6625a615ab2b10b307950a4c9a0d26f0a14bf07bc73c/vindaloo-3.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92735785ff16a6135f67c1d9f741ad17", "sha256": "203fc6001262f4c67a7ba85bcd8ffc326b739f33dfeb4e2fca20ab4d632f18d9" }, "downloads": -1, "filename": "vindaloo-3.1.1.tar.gz", "has_sig": false, "md5_digest": "92735785ff16a6135f67c1d9f741ad17", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 20364, "upload_time": "2019-09-23T12:05:59", "url": "https://files.pythonhosted.org/packages/1d/6d/bf577330e5151becc5b0cadf358fa63ba45f78db6dc412751bfe77610cc7/vindaloo-3.1.1.tar.gz" } ] }