def test_parse_huge(self): config = NginxConfig(huge_config) config.full_parse() # error logs assert_that(config.error_logs, has_length(1)) assert_that(config.error_logs, has_key('/var/log/nginx-error.log')) # access logs assert_that(config.access_logs, has_length(2)) assert_that(config.access_logs, has_item('/var/log/default.log')) assert_that(config.access_logs, has_item('/var/log/pp.log')) assert_that(config.access_logs['/var/log/pp.log'], equal_to('main')) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('main')) assert_that( config.log_formats['main'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"' ) ) # stub status url assert_that(config.stub_status_urls, has_length(2)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:80/nginx_status'))
def test_regex_status_url(self): """ Check that we could handle regex urls like location ~ /(nginx_status|status) location ~ ^/nginx_status$ """ config = NginxConfig(regex_status_config) config.full_parse() # check total amount of status urls assert_that(config.stub_status_urls, has_length(4)) # we have 4 valid locations in the regex_status/status.conf # check each location valid_urls_dict = { '1.1.1.1:80': [ '1.1.1.1:80/nginx_status', '1.1.1.1:80/status', ], '1.1.1.1:81': ['1.1.1.1:81/nginx_status'], '1.1.1.1:82': [ '1.1.1.1:82/status_weird_thing', '1.1.1.1:82/nginx_status_weird_thing', '1.1.1.1:82/status_weird_some', '1.1.1.1:82/nginx_status_weird_some' ], '1.1.1.1:84': ['1.1.1.1:84/valid_location'], } for url in config.stub_status_urls: address = url.split('/')[0] valid_urls = valid_urls_dict[address] assert_that(valid_urls, has_item(url))
def test_json(self): config = NginxConfig(json_config) config.full_parse() assert_that(config.log_formats, has_key('json')) assert_that( config.log_formats['json'], equal_to('{ "time_iso8601": "$time_iso8601", "browser": [{"modern_browser": "$modern_browser", ' '"ancient_browser": "$ancient_browser", "msie": "$msie"}], "core": [{"args": "$args", "arg": ' '{ "arg_example": "$arg_example"}, "body_bytes_sent": "$body_bytes_sent", "bytes_sent": ' '"$bytes_sent", "cookie": { "cookie_example": "$cookie_example" }, "connection": "$connection", ' '"connection_requests": "$connection_requests", "content_length": "$content_length", ' '"content_type": "$content_type", "document_root": "$document_root", "document_uri": ' '"$document_uri","host": "$host", "hostname": "$hostname", "http": { "http_example": ' '"$http_example" }, "https": "$https", "is_args": "$is_args", "limit_rate": "$limit_rate", ' '"msec": "$msec", "nginx_version": "$nginx_version", "pid": "$pid", "pipe": "$pipe", ' '"proxy_protocol_addr": "$proxy_protocol_addr", "query_string": "$query_string", "realpath_root": ' '"$realpath_root", "remote_addr": "$remote_addr", "remote_port": "$remote_port", "remote_user": '******'"$remote_user", "request": "$request", "request_body": "$request_body", "request_body_file": ' '"$request_body_file", "request_completion": "$request_completion", "request_filename": ' '"$request_filename", "request_length": "$request_length", "request_method": "$request_method", ' '"request_time": "$request_time", "request_uri": "$request_uri", "scheme": "$scheme", ' '"sent_http_": { "sent_http_example": "$sent_http_example" }, "server_addr": "$server_addr", ' '"server_name": "$server_name", "server_port": "$server_port", "server_protocol": ' '"$server_protocol", "status": "$status", "tcpinfo_rtt": "$tcpinfo_rtt", "tcpinfo_rttvar": ' '"$tcpinfo_rttvar", "tcpinfo_snd_cwnd": "$tcpinfo_snd_cwnd", "tcpinfo_rcv_space": ' '"$tcpinfo_rcv_space", "uri": "$uri" }]}') )
def test_parse_simple_exclude_combined(self): """Check that config.full_parse() obeys exclude_logs from app_config with combined ignore""" context.app_config['nginx']['exclude_logs'] = '/var/log/nginx/*.log' config = NginxConfig(simple_config) config.full_parse() del context.app_config['nginx']['exclude_logs'] assert_that(config.error_logs, empty()) assert_that(config.access_logs, empty()) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"' ) ) # stub status urls assert_that(config.stub_status_urls, has_length(1)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:81/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(1)) assert_that(config.plus_status_external_urls[0], equal_to('127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_length(1)) assert_that(config.plus_status_internal_urls[0], equal_to('127.0.0.1:81/plus_status'))
def test_broken(self): config = NginxConfig(broken_config) config.full_parse() assert_that( config.tree, has_entries({ 'status': 'failed', 'errors': has_length(2), 'config': contains( has_entries({ 'file': '/amplify/test/fixtures/nginx/broken/nginx.conf', 'status': 'failed', 'errors': contains( has_entries({ 'line': 9, 'error': '"http" directive is not allowed here in /amplify/test/fixtures/nginx/broken/nginx.conf:9' }), has_entries({ 'line': 11, 'error': 'unexpected end of file, expecting "}" in /amplify/test/fixtures/nginx/broken/nginx.conf:11' })) })) }))
def test_parse_simple(self): config = NginxConfig(simple_config) config.full_parse() # error logs assert_that(config.error_logs, has_length(1)) assert_that(config.error_logs, has_key('/var/log/nginx/error.log')) assert_that(config.error_logs.values(), only_contains( has_entries( log_level=instance_of(str), permissions=matches_regexp('[0-7]{4}'), readable=instance_of(bool) ) )) # access logs assert_that(config.access_logs, has_length(2)) assert_that(config.access_logs, has_item('/var/log/nginx/access.log')) assert_that(config.access_logs, has_item('/var/log/nginx/superaccess.log')) assert_that(config.access_logs['/var/log/nginx/access.log']['log_format'], equal_to('super_log_format')) assert_that(config.access_logs.values(), only_contains( has_entries( log_format=any_of(is_in(config.log_formats), none()), permissions=matches_regexp('[0-7]{4}'), readable=instance_of(bool) ) )) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"' ) ) # stub status urls assert_that(config.stub_status_urls, has_length(1)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:81/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(1)) assert_that(config.plus_status_external_urls[0], equal_to('127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_length(1)) assert_that(config.plus_status_internal_urls[0], equal_to('127.0.0.1:81/plus_status')) # api urls assert_that(config.api_external_urls, has_length(1)) assert_that(config.api_external_urls[0], equal_to('127.0.0.1:81/api')) assert_that(config.api_internal_urls, has_length(1)) assert_that(config.api_internal_urls[0], equal_to('127.0.0.1:81/api'))
def test_parse_simple_exclude_multiple(self): """Check that config.full_parse() obeys exclude_logs from app_config with multiple ignores""" context.app_config['nginx'][ 'exclude_logs'] = '/var/log/nginx/super*.log,error*' config = NginxConfig(simple_config) config.full_parse() del context.app_config['nginx']['exclude_logs'] assert_that(config.error_logs, empty()) assert_that(config.access_logs, has_length(1)) assert_that(config.access_logs, has_item('/var/log/nginx/access.log')) assert_that( config.access_logs['/var/log/nginx/access.log']['log_format'], equal_to('super_log_format')) assert_that( config.access_logs.values(), only_contains( has_entries(log_format=any_of(is_in(config.log_formats), none()), permissions=matches_regexp('[0-7]{4}'), readable=instance_of(bool)))) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"')) # stub status urls assert_that(config.stub_status_urls, has_length(2)) assert_that(config.stub_status_urls, has_item('http://127.0.0.1:81/basic_status')) assert_that(config.stub_status_urls, has_item('https://127.0.0.1:443/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(2)) assert_that(config.plus_status_external_urls, has_item('http://127.0.0.1:81/plus_status')) assert_that(config.plus_status_external_urls, has_item('https://127.0.0.1:443/plus_status')) assert_that(config.plus_status_internal_urls, has_length(2)) assert_that(config.plus_status_internal_urls, has_item('http://127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_item('https://127.0.0.1:443/plus_status'))
def test_parse_tabbed_config(self): config = NginxConfig(tabs_config) config.full_parse() assert_that(config.log_formats, has_key('main')) assert_that( config.log_formats['main'], equal_to('"$time_local"\t"$remote_addr"\t"$http_host"\t"$request"\t' '"$status"\t"$body_bytes_sent\t"$http_referer"\t' '"$http_user_agent"\t"$http_x_forwarded_for"') )
def test_ssl(self): config = NginxConfig(ssl_simple_config) config.full_parse() config.run_ssl_analysis() ssl_certificates = config.ssl_certificates assert_that(ssl_certificates, has_length(1)) # check contents assert_that(ssl_certificates.keys()[0], ends_with('certs.d/example.com.crt')) assert_that(ssl_certificates.values()[0], has_item('names'))
def test_proxy_buffers_simple(self): config = NginxConfig(proxy_buffers_simple_config) config.full_parse() assert_that(config.tree, has_key('http')) http_bucket = config.tree['http'][0] assert_that(http_bucket, has_key('proxy_buffering')) assert_that(http_bucket, has_key('proxy_buffers')) assert_that(config.parser_errors, has_length(0)) assert_that(config.test_errors, has_length(0))
def test_permissions_and_mtime_affect_checksum(self): """ Check that changing permissions or mtime affect checksum """ config = NginxConfig(simple_config) config.full_parse() old_checksum = config.checksum() os.system('touch %s' % (os.getcwd() + '/test/fixtures/nginx/simple/conf.d/')) config.full_parse() new_checksum = config.checksum() assert_that(new_checksum, not_(equal_to(old_checksum)))
def test_fastcgi(self): config = NginxConfig(fastcgi_config) config.full_parse() assert_that(config.tree, has_key('http')) http_bucket = config.tree['http'][0] server_bucket = http_bucket['server'][0][0] # fastcgi server tree location = server_bucket['location']['~ \\.php$'][0] # fastcgi pass location tree assert_that(location, has_key('fastcgi_pass')) assert_that(location, has_key('fastcgi_param')) assert_that(location['fastcgi_param'], has_length(17))
def test_parse_complex(self): config = NginxConfig(complex_config) config.full_parse() context.log.info(config.index) context.log.info(config.tree) context.log.info(config.files) context.log.info(config.checksum()) assert_that(config.error_logs, empty()) assert_that(config.access_logs, empty()) assert_that(config.log_formats, empty()) assert_that(config.stub_status_urls, empty())
def test_parse_tabbed_config(self): config = NginxConfig(tabs_config) config.full_parse() # common structure assert_that( config.subtree, contains(has_entries({'directive': 'user'}), has_entries({'directive': 'worker_processes'}), has_entries({'directive': 'error_log'}), has_entries({'directive': 'pid'}), has_entries({'directive': 'events'}), has_entries({'directive': 'http'}))) http = config.subtree[5]['block'] assert_that( http, contains( has_entries({'directive': 'charset'}), has_entries({'directive': 'log_format'}), has_entries({'directive': 'access_log'}), has_entries({'directive': 'proxy_cache_path'}), has_entries({'directive': 'sendfile'}), has_entries({'directive': 'keepalive_timeout'}), has_entries({'directive': 'gzip'}), has_entries({'directive': 'gzip_types'}), has_entries({'directive': 'root'}), has_entries({'directive': 'server'}), has_entries({'directive': 'server'}), has_entries({'directive': 'upstream'}), has_entries({'directive': 'server'}), has_entries({'directive': 'server'}), )) log_format_args = http[1]['args'] assert_that(log_format_args[0], equal_to('main')) assert_that( log_format_args[1], equal_to( '"$time_local"\\t"$remote_addr"\\t"$http_host"\\t"$request"\\t' '"$status"\\t"$body_bytes_sent\\t"$http_referer"\\t' '"$http_user_agent"\\t"$http_x_forwarded_for"')) assert_that( config.log_formats['main'], equal_to( '"$time_local"\t"$remote_addr"\t"$http_host"\t"$request"\t' '"$status"\t"$body_bytes_sent\t"$http_referer"\t' '"$http_user_agent"\t"$http_x_forwarded_for"'))
def test_proxy_buffers_complex(self): config = NginxConfig(proxy_buffers_complex_config) config.full_parse() assert_that(config.tree, has_key('http')) http_bucket = config.tree['http'][0] assert_that(http_bucket, has_key('proxy_buffering')) assert_that(http_bucket, has_key('proxy_buffers')) location_bucket = config.tree['http'][0]['server'][0][0]['location']['/'][0] assert_that(location_bucket, has_key('proxy_buffering')) assert_that(location_bucket, has_key('proxy_buffers')) assert_that(config.parser_errors, has_length(0)) assert_that(config.test_errors, has_length(0))
def test_parse_simple(self): config = NginxConfig(simple_config) config.full_parse() # error logs assert_that(config.error_logs, has_length(1)) assert_that(config.error_logs, has_key('/var/log/nginx/error.log')) # access logs assert_that(config.access_logs, has_length(2)) assert_that(config.access_logs, has_item('/var/log/nginx/access.log')) assert_that(config.access_logs, has_item('/var/log/nginx/superaccess.log')) assert_that(config.access_logs['/var/log/nginx/access.log'], equal_to('super_log_format')) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"')) # stub status urls assert_that(config.stub_status_urls, has_length(1)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:81/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(1)) assert_that(config.plus_status_external_urls[0], equal_to('127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_length(1)) assert_that(config.plus_status_internal_urls[0], equal_to('127.0.0.1:81/plus_status'))
def test_parse_complex(self): config = NginxConfig(complex_config) config.full_parse() context.log.info(config.index) context.log.info(config.tree) context.log.info(config.files) context.log.info(config.checksum()) # error logs assert_that(config.error_logs, has_length(0)) # access logs assert_that(config.access_logs, has_length(0)) # log formats assert_that(config.log_formats, has_length(0)) # stub status url assert_that(config.stub_status_urls, has_length(0))
def test_parse_wildcard_dir(self): """ Tests wild card directory handling. """ config = NginxConfig(wildcard_directory_config) config.full_parse() assert_that( config.directory_map, has_key( '/amplify/test/fixtures/nginx/wildcard_directory/data/www/test.domain.info/config/nginx/' ) ) files = config.directory_map[ '/amplify/test/fixtures/nginx/wildcard_directory/data/www/test.domain.info/config/nginx/' ]['files'] assert_that( files, has_key('/amplify/test/fixtures/nginx/wildcard_directory/data/www/test.domain.info/config/nginx/test.conf') )
def test_parse_simple_exclude_multiple(self): """Check that config.full_parse() obeys exclude_logs from app_config with multiple ignores""" context.app_config['nginx']['exclude_logs'] = '/var/log/nginx/super*.log,error*' config = NginxConfig(simple_config) config.full_parse() del context.app_config['nginx']['exclude_logs'] # error logs assert_that(config.error_logs, has_length(0)) # access logs assert_that(config.access_logs, has_length(1)) assert_that(config.access_logs, has_item('/var/log/nginx/access.log')) assert_that(config.access_logs['/var/log/nginx/access.log'], equal_to('super_log_format')) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"' ) ) # stub status urls assert_that(config.stub_status_urls, has_length(1)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:81/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(1)) assert_that(config.plus_status_external_urls[0], equal_to('127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_length(1)) assert_that(config.plus_status_internal_urls[0], equal_to('127.0.0.1:81/plus_status'))
def test_parse_simple(self): config = NginxConfig(simple_config) config.full_parse() # error logs assert_that(config.error_logs, has_length(1)) assert_that(config.error_logs, has_key('/var/log/nginx/error.log')) # access logs assert_that(config.access_logs, has_length(2)) assert_that(config.access_logs, has_item('/var/log/nginx/access.log')) assert_that(config.access_logs, has_item('/var/log/nginx/superaccess.log')) assert_that(config.access_logs['/var/log/nginx/access.log'], equal_to('super_log_format')) # log formats assert_that(config.log_formats, has_length(1)) assert_that(config.log_formats, has_item('super_log_format')) assert_that( config.log_formats['super_log_format'], equal_to( '$remote_addr - $remote_user [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" ' + 'rt="$request_time" ua="$upstream_addr" us="$upstream_status" ' + 'ut="$upstream_response_time" "$gzip_ratio"' ) ) # stub status urls assert_that(config.stub_status_urls, has_length(1)) assert_that(config.stub_status_urls[0], equal_to('127.0.0.1:81/basic_status')) # status urls assert_that(config.plus_status_external_urls, has_length(1)) assert_that(config.plus_status_external_urls[0], equal_to('127.0.0.1:81/plus_status')) assert_that(config.plus_status_internal_urls, has_length(1)) assert_that(config.plus_status_internal_urls[0], equal_to('127.0.0.1:81/plus_status'))
class NginxObject(AbstractObject): type = 'nginx' def __init__(self, **kwargs): super(NginxObject, self).__init__(**kwargs) self.root_uuid = self.data.get('root_uuid') or context.objects.root_object.uuid if context.objects.root_object else None self.local_id_cache = self.data['local_id'] # Assigned by manager self.pid = self.data['pid'] self.version = self.data['version'] self.workers = self.data['workers'] self.prefix = self.data['prefix'] self.bin_path = self.data['bin_path'] self.conf_path = self.data['conf_path'] default_config = context.app_config['containers'][self.type] self.upload_config = self.data.get('upload_config') or default_config.get('upload_config', False) self.run_config_test = self.data.get('run_test') or default_config.get('run_test', False) self.upload_ssl = self.data.get('upload_ssl') or default_config.get('upload_ssl', False) self.config = NginxConfig(self.conf_path, prefix=self.prefix) self.config.full_parse() self.plus_status_external_url, self.plus_status_internal_url = self.get_alive_plus_status_urls() self.plus_status_enabled = True if (self.plus_status_external_url or self.plus_status_internal_url) else False self.stub_status_url = self.get_alive_stub_status_url() self.stub_status_enabled = True if self.stub_status_url else False self.processes = [] self.filters = [] # filters for raw_filter in self.data.get('filters') or []: self.filters.append(Filter(**raw_filter)) # meta meta_collector_class = NginxCommonMetaCollector if host.os_name() == 'linux': if host.linux_name() in ('ubuntu', 'debian'): meta_collector_class = NginxDebianMetaCollector elif host.linux_name() in ('centos',): meta_collector_class = NginxCentosMetaCollector self.collectors = [ meta_collector_class( object=self, interval=self.intervals['meta'] ), NginxMetricsCollector( object=self, interval=self.intervals['metrics'] ), NginxConfigCollector( object=self, interval=self.intervals['configs'], ) ] # access logs for log_filename, format_name in self.config.access_logs.iteritems(): log_format = self.config.log_formats.get(format_name) try: self.collectors.append( NginxAccessLogsCollector( object=self, interval=self.intervals['logs'], filename=log_filename, log_format=log_format, ) ) # Send access log discovery event. self.eventd.event(level=INFO, message='nginx access log %s found' % log_filename) except IOError as e: exception_name = e.__class__.__name__ context.log.error( 'failed to start reading log %s due to %s (maybe has no rights?)' % (log_filename, exception_name) ) context.log.debug('additional info:', exc_info=True) # error logs for log_filename, log_level in self.config.error_logs.iteritems(): try: self.collectors.append( NginxErrorLogsCollector( object=self, interval=self.intervals['logs'], filename=log_filename, level=log_level ) ) # Send error log discovery event. self.eventd.event(level=INFO, message='nginx error log %s found' % log_filename) except IOError as e: exception_name = e.__class__.__name__ context.log.error( 'failed to start reading log %s due to %s (maybe has no rights?)' % (log_filename, exception_name) ) context.log.debug('additional info:', exc_info=True) @property def definition(self): return {'type': self.type, 'local_id': self.local_id, 'root_uuid': self.root_uuid} def get_alive_stub_status_url(self): """ Tries to get alive stub_status url Records some events about it :return: """ urls_to_check = self.config.stub_status_urls if 'stub_status' in context.app_config.get('nginx', {}): predefined_uri = context.app_config['nginx']['stub_status'] urls_to_check.append(http.resolve_uri(predefined_uri)) stub_status_url = self.__get_alive_status(urls_to_check) if stub_status_url: # Send stub detected event self.eventd.event( level=INFO, message='nginx stub_status detected, %s' % stub_status_url ) else: self.eventd.event( level=INFO, message='nginx stub_status not found in nginx config' ) return stub_status_url def get_alive_plus_status_urls(self): """ Tries to get alive plus urls There are two types of plus status urls: internal and external - internal are for the agent and usually they have the localhost ip in address - external are for the browsers and usually they have a normal server name Returns a tuple of str or Nones - (external_url, internal_url) Even if external status url is not responding (cannot be accesible from the host) we should return it to show in our UI :return: (str or None, str or None) """ internal_urls = self.config.plus_status_internal_urls external_urls = self.config.plus_status_external_urls if 'plus_status' in context.app_config.get('nginx', {}): predefined_uri = context.app_config['nginx']['plus_status'] internal_urls.append(http.resolve_uri(predefined_uri)) internal_status_url = self.__get_alive_status(internal_urls, json=True) if internal_status_url: self.eventd.event( level=INFO, message='nginx internal plus_status detected, %s' % internal_status_url ) external_status_url = self.__get_alive_status(external_urls, json=True) if len(self.config.plus_status_external_urls) > 0: if not external_status_url: external_status_url = 'http://%s' % self.config.plus_status_external_urls[0] self.eventd.event( level=INFO, message='nginx external plus_status detected, %s' % external_status_url ) return external_status_url, internal_status_url def __get_alive_status(self, url_list, json=False): """ Tries to find alive status url Returns first alive url or None if all founded urls are not responding :param url_list: [] of urls :param json: bool - will try to encode json if True :return: None or str """ for url in url_list: for proto in ('http://', 'https://'): full_url = '%s%s' % (proto, url) if not url.startswith('http') else url try: status_response = context.http_client.get(full_url, timeout=0.5, json=json, log=False) if status_response: if json or 'Active connections' in status_response: return full_url else: context.log.debug('bad response from stub/plus status url %s' % full_url) except: context.log.debug('bad response from stub/plus status url %s' % full_url) return None
def collect(self): try: config = NginxConfig( self.object.conf_path, binary=self.object.bin_path, prefix=self.object.prefix ) # check if config is changed (changes are: new files/certs, new mtimes) config_files, config_dirs = config.collect_structure(include_ssl_certs=self.object.upload_ssl) if config_files == self.previous_files and config_dirs == self.previous_directories: return # parse config tree config.full_parse() # Send event for parsing nginx config. # Use config.parser.filename to account for default value defined in NginxConfigParser. self.object.eventd.event( level=INFO, message='nginx config parsed, read from %s' % config.filename, ) for error in config.parser_errors: self.object.eventd.event(level=WARNING, message=error) # run ssl checks if self.object.upload_ssl: config.run_ssl_analysis() else: context.log.info('ssl analysis skipped due to users settings') # run upload checksum = config.checksum() if self.object.upload_config: self.upload(config, checksum) if self.previous_checksum: # config changed, so we need to restart the object self.object.need_restart = True else: # otherwise run test if self.object.run_config_test and config.total_size() < 20*1024*1024: # 20 MB run_time = config.run_test() # send event for testing nginx config if config.test_errors: self.object.eventd.event(level=WARNING, message='nginx config test failed') else: self.object.eventd.event(level=INFO, message='nginx config tested ok') for error in config.test_errors: self.object.eventd.event(level=CRITICAL, message=error) # stop -t if it took too long if run_time > context.app_config['containers']['nginx']['max_test_duration']: context.app_config['containers']['nginx']['run_test'] = False context.app_config.mark_unchangeable('run_test') self.object.eventd.event( level=WARNING, message='%s -t -c %s took %s seconds, disabled until agent restart' % ( config.binary, config.filename, run_time ) ) self.object.run_config_test = False self.previous_checksum = checksum self.previous_files = copy.copy(config_files) self.previous_directories = copy.copy(config_dirs) except Exception as e: exception_name = e.__class__.__name__ context.log.error('failed to collect due to %s' % exception_name) context.log.debug('additional info:', exc_info=True) self.object.eventd.event( level=INFO, message='nginx config parser failed, path %s' % self.object.conf_path, onetime=True )
sys.exit(1) if options.config.startswith('~'): filename = options.config.replace('~', os.path.expanduser('~')) elif not options.config.startswith('/'): filename = os.getcwd() + '/' + options.config else: filename = options.config start_time = time.time() cfg = NginxConfig(filename=filename) print_args = dict(indent=4, sort_keys=True) if options.pretty else dict() if not options.light: cfg.full_parse() print('\033[32mConfig tree for %s\033[0m' % filename) print(json.dumps(cfg.tree, **print_args)) print('\n\033[32mConfig index for %s\033[0m' % filename) print(json.dumps(cfg.index, **print_args)) print('\n\033[32mConfig files for %s\033[0m' % filename) print(json.dumps(cfg.files, **print_args)) print('\n\033[32mStub/plus status %s\033[0m' % filename) print(json.dumps(cfg.stub_status_urls, **print_args)) print(json.dumps(cfg.plus_status_external_urls, **print_args)) print(json.dumps(cfg.plus_status_internal_urls, **print_args))
def test_broken(self): config = NginxConfig(broken_config) config.full_parse() assert_that(config.tree, equal_to({})) assert_that(config.parser_errors, has_length(1))
def test_broken_includes(self): config = NginxConfig(huge_config) config.full_parse() assert_that(config.tree, not_(equal_to({}))) assert_that(config.parser_errors, has_length(5)) # 5 missing includes