Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

149 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pyhaproxy PyPi Build Status

It's a Python library to parse haproxy config file. Thanks to 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.

Install

This project uses nose for unit testing, but with no more Python libraries dependencies for running.

  • Suppose that you have virtualenv installed, if not, please go here to install
  • Create a virutalenv and activate it,
$ virtualenv --no-site-packages pyhaproxy
$ source pyhaproxy/bin/activate
  • User pip (pip install pyhaproxy) or setuptools (easy_install pyhaproxy) to install it
  • Install nose dependency for unittest
(pyhaproxy)$ pip install -r requirements.txt

Example

Here is the simple example to show how to use it. See unittest file test.py for more usage details.

#!/usr/bin/env python
# -*- coding: utf8 -*-

from pyhaproxy.parse import Parser
from pyhaproxy.render import Render
import pyhaproxy.config as config


# Build the configuration instance by calling Parser('config_file').build_configuration()
cfg_parser = Parser('haproxy.cfg')
configuration = cfg_parser.build_configuration()

# Get the global section
print configuration.globall  # the `global` is keyword of Python, so name it `globall`
print configuration.globall.options()  # get the 'option ...' config lines
print configuration.globall.configs()  # get config lines except 'option ...' ones


# Get all the frontend sections
frontend_sections = configuration.frontends

# Get frontend sections specifics
for fe_section in frontend_sections:
    # Get the name, host, port of the frontend section
    print fe_section.name, fe_section.host, fe_section.port
    print fe_section.options()
    print fe_section.configs()


# Find the frontend by name
the_fe_section = configuration.frontend(the_fe_section_name)

'''To get other sections is ditto.
'''


# Operates the ACL in a frontend, it much likes operating a list

#   Get all the ACLs defined in the frontend section
acls = the_fe_section.acls()   # return list(config.Acl)

#   Find the specified ACL
acl_instance = the_fe_section.acl(the_acl_name)   # return config.Acl

#   Modify existing ACL
acl_instance.value = 'hdr(host) -i modified.example.com'

#   Append the ACL into the frontend section
#       for version <= 0.2.4
the_fe_section.acls().append(config.Acl(acl_name, acl_value))
#       for version > 0.2.4
the_fe_section.add_acl(config.Acl(acl_name, acl_value))        

#   Remove ACL
#       for version <= 0.2.4
acl_instance = the_fe_section.acl(the_acl_name)
the_fe_section.acls().remove(acl_instance)
#       for version > 0.2.4
the_fe_section.remove_acl(the_acl_name)           


# Operates the use_backend / default_backend configs in a frontend

#   Get all the backend configs
usebackends = the_fe_section.usebackends()  # return list(config.UseBackend)
for usebe in usebackends:
    # Get the using backend name, operator, condition
    print usebe.backend_name, usebe.operator, usebe.backend_condition
    # Determine if it's `default_backend` line
    print usebe.is_default
#   Add a new `use_backend` or `default_backend` line
#       for version <= 0.2.4
the_fe_section.usebackends().append(config.UseBackend(backend_name, operator, backend_condition, is_default))
#       for version > 0.2.4
the_fe_section.add_usebackend(config.UseBackend(backend_name, operator, backend_condition, is_default))


# Operates the Server in a backend
the_be_section = configuration.backend(the_be_section_name)
#   Get all the Server lines in backend section
servers = the_be_section.servers()  # return list(config.Server)
#   Find the specified Server
the_server = the_be_section.server(the_server_name)  # return config.Server
#   Get the Server name, host, port
print the_server.name, the_server.host, the_server.port
#   Get the Server attributes, for line: `server web_server_1 10.1.1.2:80 cookie 1 check inter 2000 rise 3`
print the_server.attributes  # it's is ['cookie', 1, 'check', 'inter', 2000, 'rise', 3]
#   Remove the Server by name
#       for version <= 0.2.4
the_be_section.servers().remove(the_server)
#       for version > 0.2.4
the_be_section.remove_server(server_name)


# Render out to the cfg file
cfg_render = Render(configuration)
cfg_render.dumps_to('./hatest.cfg')  # you will see hatest.cfg which is same to the `haproxy.cfg` parsed previously

Finished

  • Parse global section
  • Parse frontend sections
  • Parse bind config lines
  • Parse backend sections
  • Parse defaults sections
  • Parse userlist sections
  • Parse listen sections
  • Parse acl config lines
  • Parse use_backend and default_backend config lines
  • Render global section
  • Render frontend section
  • Render backend sections
  • Render defaults sections
  • Render userlist sections
  • Render listen sections

TODO

  • Link backend with frontend by acl

Unittest

Use nose unit test framework

(pyhaproxy)$ nosetests -sv test.py

Thanks

  • Inspired by @subakva 's haproxy-tools
  • Use canopy of @jcoglan for PEG parsing and Python code auto-generating

About

Python library to parse haproxy configurations

Topics

Resources

Stars

56 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages