{"id":21055136,"url":"https://github.com/imjoey/pyhaproxy","last_synced_at":"2025-05-15T23:32:19.890Z","repository":{"id":61593501,"uuid":"46701859","full_name":"imjoey/pyhaproxy","owner":"imjoey","description":"Python library to parse haproxy configurations","archived":false,"fork":false,"pushed_at":"2019-12-06T09:22:34.000Z","size":92,"stargazers_count":54,"open_issues_count":4,"forks_count":21,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-03T16:48:01.141Z","etag":null,"topics":["configuration","haproxy","parse","parse-sections","python-library"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imjoey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-23T06:47:31.000Z","updated_at":"2025-03-27T06:46:25.000Z","dependencies_parsed_at":"2022-10-20T11:45:14.839Z","dependency_job_id":null,"html_url":"https://github.com/imjoey/pyhaproxy","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjoey%2Fpyhaproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjoey%2Fpyhaproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjoey%2Fpyhaproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjoey%2Fpyhaproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imjoey","download_url":"https://codeload.github.com/imjoey/pyhaproxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254442340,"owners_count":22071863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","haproxy","parse","parse-sections","python-library"],"created_at":"2024-11-19T16:35:58.649Z","updated_at":"2025-05-15T23:32:14.783Z","avatar_url":"https://github.com/imjoey.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pyhaproxy ![PyPi](https://img.shields.io/pypi/v/pyhaproxy.svg)   ![Build Status](https://travis-ci.org/imjoey/pyhaproxy.svg?branch=master)\nIt's a Python library to parse haproxy config file. Thanks to [canopy](https://github.com/jcoglan/canopy), which I use for auto-generating Python codes by PEG grammar. But the 'Extension methods for node' feature in canopy seems broken, I always encounter the MRO errors when running `parse` function. So I modify the generated codes which mainly rename the `TreeNode*` to specified treenode name, eg: GlobalSection, GlobalHeader, BackendHeader, and also complement missing attributes.\n\n\n# Install\nThis project uses nose for unit testing, but with no more Python libraries dependencies for running.\n\n* Suppose that you have virtualenv installed, if not, please go [here](https://virtualenv.readthedocs.org/en/latest/installation.html) to install\n* Create a virutalenv and activate it,\n```bash\n$ virtualenv --no-site-packages pyhaproxy\n$ source pyhaproxy/bin/activate\n```\n* User pip (`pip install pyhaproxy`) or setuptools (`easy_install pyhaproxy`) to install it\n* Install nose dependency for unittest\n```bash\n(pyhaproxy)$ pip install -r requirements.txt\n```\n\n\n# Example\nHere is the simple example to show how to use it. See unittest file [test.py](https://github.com/imjoey/pyhaproxy/blob/master/pyhaproxy/test.py) for more usage details.\n\n```python\n#!/usr/bin/env python\n# -*- coding: utf8 -*-\n\nfrom pyhaproxy.parse import Parser\nfrom pyhaproxy.render import Render\nimport pyhaproxy.config as config\n\n\n# Build the configuration instance by calling Parser('config_file').build_configuration()\ncfg_parser = Parser('haproxy.cfg')\nconfiguration = cfg_parser.build_configuration()\n\n# Get the global section\nprint configuration.globall  # the `global` is keyword of Python, so name it `globall`\nprint configuration.globall.options()  # get the 'option ...' config lines\nprint configuration.globall.configs()  # get config lines except 'option ...' ones\n\n\n# Get all the frontend sections\nfrontend_sections = configuration.frontends\n\n# Get frontend sections specifics\nfor fe_section in frontend_sections:\n    # Get the name, host, port of the frontend section\n    print fe_section.name, fe_section.host, fe_section.port\n    print fe_section.options()\n    print fe_section.configs()\n\n\n# Find the frontend by name\nthe_fe_section = configuration.frontend(the_fe_section_name)\n\n'''To get other sections is ditto.\n'''\n\n\n# Operates the ACL in a frontend, it much likes operating a list\n\n#   Get all the ACLs defined in the frontend section\nacls = the_fe_section.acls()   # return list(config.Acl)\n\n#   Find the specified ACL\nacl_instance = the_fe_section.acl(the_acl_name)   # return config.Acl\n\n#   Modify existing ACL\nacl_instance.value = 'hdr(host) -i modified.example.com'\n\n#   Append the ACL into the frontend section\n#       for version \u003c= 0.2.4\nthe_fe_section.acls().append(config.Acl(acl_name, acl_value))\n#       for version \u003e 0.2.4\nthe_fe_section.add_acl(config.Acl(acl_name, acl_value))        \n\n#   Remove ACL\n#       for version \u003c= 0.2.4\nacl_instance = the_fe_section.acl(the_acl_name)\nthe_fe_section.acls().remove(acl_instance)\n#       for version \u003e 0.2.4\nthe_fe_section.remove_acl(the_acl_name)           \n\n\n# Operates the use_backend / default_backend configs in a frontend\n\n#   Get all the backend configs\nusebackends = the_fe_section.usebackends()  # return list(config.UseBackend)\nfor usebe in usebackends:\n    # Get the using backend name, operator, condition\n    print usebe.backend_name, usebe.operator, usebe.backend_condition\n    # Determine if it's `default_backend` line\n    print usebe.is_default\n#   Add a new `use_backend` or `default_backend` line\n#       for version \u003c= 0.2.4\nthe_fe_section.usebackends().append(config.UseBackend(backend_name, operator, backend_condition, is_default))\n#       for version \u003e 0.2.4\nthe_fe_section.add_usebackend(config.UseBackend(backend_name, operator, backend_condition, is_default))\n\n\n# Operates the Server in a backend\nthe_be_section = configuration.backend(the_be_section_name)\n#   Get all the Server lines in backend section\nservers = the_be_section.servers()  # return list(config.Server)\n#   Find the specified Server\nthe_server = the_be_section.server(the_server_name)  # return config.Server\n#   Get the Server name, host, port\nprint the_server.name, the_server.host, the_server.port\n#   Get the Server attributes, for line: `server web_server_1 10.1.1.2:80 cookie 1 check inter 2000 rise 3`\nprint the_server.attributes  # it's is ['cookie', 1, 'check', 'inter', 2000, 'rise', 3]\n#   Remove the Server by name\n#       for version \u003c= 0.2.4\nthe_be_section.servers().remove(the_server)\n#       for version \u003e 0.2.4\nthe_be_section.remove_server(server_name)\n\n\n# Render out to the cfg file\ncfg_render = Render(configuration)\ncfg_render.dumps_to('./hatest.cfg')  # you will see hatest.cfg which is same to the `haproxy.cfg` parsed previously\n\n```\n\n\n# Finished\n- [x] Parse `global` section\n- [x] Parse `frontend` sections\n- [x] Parse `bind` config lines\n- [x] Parse `backend` sections\n- [x] Parse `defaults` sections\n- [x] Parse `userlist` sections\n- [x] Parse `listen` sections\n- [x] Parse `acl` config lines\n- [x] Parse `use_backend` and `default_backend` config lines\n- [x] Render `global` section\n- [x] Render `frontend` section\n- [x] Render `backend` sections\n- [x] Render `defaults` sections\n- [x] Render `userlist` sections\n- [x] Render `listen` sections\n\n\n# TODO\n- [ ] Link `backend` with `frontend` by `acl`\n\n\n# Unittest\nUse nose unit test framework\n```bash\n(pyhaproxy)$ nosetests -sv test.py\n```\n\n\n# Thanks\n* Inspired by @subakva 's [haproxy-tools](https://github.com/subakva/haproxy-tools)\n* Use [canopy](https://github.com/jcoglan/canopy) of @jcoglan for PEG parsing and Python code auto-generating\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimjoey%2Fpyhaproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimjoey%2Fpyhaproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimjoey%2Fpyhaproxy/lists"}