Source code for insights.parsers.nginx_conf

NginxConf - file ``/etc/nginx/nginx.conf`` and other Nginx configuration files

Parse the keyword-and-value of an Nginx configuration file.

Generally, each line is split on the first space into key and value, leading
and trailing space being ignored.

Example nginx.conf file::

    user       root
    worker_processes  5;
    error_log  logs/error.log;
    pid        logs/;
    worker_rlimit_nofile 8192;

    events {
      worker_connections  4096;

    mail {
      auth_http  localhost:9000/cgi-bin/auth;
      server {
        listen   143;
        protocol imap;

    http {
      include  /etc/nginx/conf.d/*.conf
      index    index.html index.htm index.php;

      default_type application/octet-stream;
      log_format   main '$remote_addr - $remote_user [$time_local]  $status '
                        '"$request" $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';
      access_log   logs/access.log  main;
      sendfile     on;
      tcp_nopush   on;
      server_names_hash_bucket_size 128;

      server { # php/fastcgi
        listen       80;
        access_log   logs/domain1.access.log  main;
        root         html;

        location ~ \.php$ {

      server { # simple reverse-proxy
        listen       80;
        access_log   logs/domain2.access.log  main;

        location ~ ^/(images|javascript|js|css|flash|media|static)/  {
          root    /var/www/virtual/;
          expires 30d;

        location / {

      map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;

      upstream websocket {

      upstream big_server_com {
        server weight=5;
        server weight=5;

      server { # simple load balancing
        listen          80;
        access_log      logs/big.server.access.log main;

        location / {
          proxy_pass      http://big_server_com;


    >>> nginxconf = NginxConf(context_wrap(NGINXCONF))
    >>> nginxconf['user']
    >>> nginxconf['events']['worker_connections'] # Values are all kept as strings.
    >>> nginxconf['mail']['server'][0]['listen']
    >>> nginxconf['http']['access_log']
    'logs/access.log  main'
    >>> nginxconf['http']['server'][0]['location'][0]['fastcgi_pass']

from .. import parser, LegacyItemAccess, Parser, get_active_lines
from ..specs import Specs
from insights.contrib.nginxparser import create_parser, UnspacedList
from insights.util import deprecated

[docs]@parser(Specs.nginx_conf) class NginxConf(Parser, LegacyItemAccess): """ .. warning:: This parser is deprecated, please import :py:class:`insights.combiners.nginx_conf.NginxConfTree` instead. Class for ``nginx.conf`` and ``conf.d`` configuration files. Gerenally nginx.conf is writed as key-value format. It has a mail section and several sections, http, mail, events, etc. They are unique, and subsection server and location in http section could be duplicate, so the value of these subsections may be list. """ def __init__(self, *args, **kwargs): deprecated(NginxConf, "Import NginxConfTree from insights.combiners.nginx_conf instead") super(NginxConf, self).__init__(*args, **kwargs)
[docs] def parse_content(self, content): list_result = UnspacedList(create_parser().parseString("\n".join(get_active_lines(content))).asList()) = self._convert_nginx_list_to_dict(list_result)
def _convert_nginx_list_to_dict(self, li): """ After parsed by create_parser(), the result is a list, it is better to convert to dict for convenience. """ def _list_depth_to_dict(self, li): """ Function to convert list whose depth is tree to dict. Generally, the section name would be a dict key, and content embraced by brace would be value. In some sections, the first item is like ['location', '/'], in this case, the convert rule is that 'location' would be the key, and add {"name":'/'} key-value to the dict value. """ dict_ret = {} if self._depth(li) == 1: return self._handle_key_value(dict_ret, li[0], li[1]) else: for sub_item in li[1]: tmp_dict = _list_depth_to_dict(self, sub_item) tmp_key = list(tmp_dict.keys())[0] tmp_val = tmp_dict[tmp_key] tmp_val = tmp_val[0] if isinstance(tmp_val, list) else tmp_val dict_ret.update(self._handle_key_value(dict_ret, tmp_key, tmp_val)) if len(li[0]) > 1: dict_ret["name"] = ' '.join(li[0][1:]) return {li[0][0]: dict_ret} dict_all = {} for item in li: dict_all.update(_list_depth_to_dict(self, item)) return dict_all def _handle_key_value(self, t_dict, key, value): """ Function to handle dict key has multi value, and return the values as list. """ # As it is possible that key "server", "location", "include" and "upstream" have multi value, set the value of dict as list. if key in ("server", "location", "include", "upstream"): if key in t_dict: val = t_dict[key] val.append(value) return {key: val} return {key: [value]} else: return {key: value} def _depth(self, l): """ Function to count the depth of a list """ if isinstance(l, list) and len(l) > 0: return 1 + max(self._depth(item) for item in l) else: return 0