import os from pyparsing import ( Literal, White, Word, alphanums, CharsNotIn, Forward, Group, Optional, OneOrMore, ZeroOrMore, pythonStyleComment) class Service(): def reload(self): os.system('service nginx reload') class Nginx(): def vhost_add(self, vhost_id, vhost, ip): nginxfile = open('%s/%s_%s.conf' % ("/etc/nginx/sites-enabled", ip, vhost_id), 'w+') config = """ server { listen 80; server_name %s; location / { proxy_pass http://%s:80; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Proxy-host $proxy_host; } } """ % (vhost, ip) nginxfile.write(config) return False def vhost_delete(self, ip, vhost_id): os.remove("/etc/nginx/sites-enabled/%s_%s.conf" % (ip, vhost_id)) return True def add_alias(self): return False def delete_alias(self): return False def delete_site(self, containser_id): return False class NginxParser(object): """ A class that parses nginx configuration with pyparsing """ # constants left_bracket = Literal("{").suppress() right_bracket = Literal("}").suppress() semicolon = Literal(";").suppress() space = White().suppress() key = Word(alphanums + "_/") value = CharsNotIn("{};,") location = CharsNotIn("{};, ") # rules assignment = (key + Optional(space + value) + semicolon) block = Forward() block << Group( Group(key + Optional(space + location)) + left_bracket + Group(ZeroOrMore(Group(assignment) | block)) + right_bracket) script = OneOrMore(Group(assignment) | block).ignore(pythonStyleComment) def __init__(self, source): self.source = source def parse(self): """ Returns the parsed tree. """ return self.script.parseString(self.source) def as_list(self): """ Returns the list of tree. """ return self.parse().asList() class NginxDumper(object): """ A class that dumps nginx configuration from the provided tree. """ def __init__(self, blocks, indentation=4): self.blocks = blocks self.indentation = indentation def __iter__(self, blocks=None, current_indent=0, spacer=' '): """ Iterates the dumped nginx content. """ blocks = blocks or self.blocks for key, values in blocks: if current_indent: yield spacer indentation = spacer * current_indent if isinstance(key, list): yield indentation + spacer.join(key) + ' {' for parameter in values: if isinstance(parameter[0], list): dumped = self.__iter__([parameter], current_indent + self.indentation) for line in dumped: yield line else: dumped = spacer.join(parameter) + ';' yield spacer * (current_indent + self.indentation) + dumped yield indentation + '}' else: yield spacer * current_indent + key +spacer + values + ';' def as_string(self): return '\n'.join(self) def to_file(self, out): for line in self: out.write(line) out.close() return out # Shortcut functions to respect Python's serialization interface # (like pyyaml, picker or json) def loads(source): return NginxParser(source).as_list() def load(_file): return loads(_file.read()) def dumps(blocks, indentation=4): return NginxDumper(blocks, indentation).as_string() def dump(blocks, _file, indentation=4): return NginxDumper(blocks, indentation).to_file(_file)