1#!/usr/bin/env python
2#############################################################################
3# Copyright (c) 2015-2018 Balabit
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 2 as published
7# by the Free Software Foundation, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17#
18# As an additional exemption you are allowed to compile & link against the
19# OpenSSL libraries as published by the OpenSSL project. See the file
20# COPYING for details.
21#
22#############################################################################
23import logging
24
25from src.common.file import File
26from src.common.operations import cast_to_list
27from src.syslog_ng_config.renderer import ConfigRenderer
28from src.syslog_ng_config.statement_group import StatementGroup
29from src.syslog_ng_config.statements.destinations.example_destination import ExampleDestination
30from src.syslog_ng_config.statements.destinations.file_destination import FileDestination
31from src.syslog_ng_config.statements.destinations.snmp_destination import SnmpDestination
32from src.syslog_ng_config.statements.filters.filter import Filter
33from src.syslog_ng_config.statements.logpath.logpath import LogPath
34from src.syslog_ng_config.statements.parsers.db_parser import DBParser
35from src.syslog_ng_config.statements.parsers.parser import Parser
36from src.syslog_ng_config.statements.rewrite.rewrite import SetPri
37from src.syslog_ng_config.statements.rewrite.rewrite import SetTag
38from src.syslog_ng_config.statements.sources.example_msg_generator_source import ExampleMsgGeneratorSource
39from src.syslog_ng_config.statements.sources.file_source import FileSource
40from src.syslog_ng_config.statements.sources.internal_source import InternalSource
41from src.syslog_ng_config.statements.sources.network_source import NetworkSource
42
43logger = logging.getLogger(__name__)
44
45
46class SyslogNgConfig(object):
47    def __init__(self, version):
48        self.__raw_config = None
49        self.__syslog_ng_config = {
50            "version": version,
51            "includes": [],
52            "global_options": {},
53            "statement_groups": [],
54            "logpath_groups": [],
55        }
56
57    @staticmethod
58    def stringify(s):
59        return '"' + s.replace('\\', "\\\\").replace('"', '\\"').replace('\n', '\\n') + '"'
60
61    def set_raw_config(self, raw_config):
62        self.__raw_config = raw_config
63
64    def write_config(self, config_path):
65        if self.__raw_config:
66            rendered_config = self.__raw_config
67        else:
68            rendered_config = ConfigRenderer(self.__syslog_ng_config).get_rendered_config()
69        logger.info("Generated syslog-ng config\n{}\n".format(rendered_config))
70
71        f = File(config_path)
72        with f.open('w+') as config_file:
73            config_file.write(rendered_config)
74
75    def set_version(self, version):
76        self.__syslog_ng_config["version"] = version
77
78    def get_version(self):
79        return self.__syslog_ng_config["version"]
80
81    def add_include(self, include):
82        self.__syslog_ng_config["includes"].append(include)
83
84    def update_global_options(self, **options):
85        self.__syslog_ng_config["global_options"].update(options)
86
87    def create_file_source(self, **options):
88        return FileSource(**options)
89
90    def create_example_msg_generator_source(self, **options):
91        return ExampleMsgGeneratorSource(**options)
92
93    def create_internal_source(self, **options):
94        return InternalSource(**options)
95
96    def create_network_source(self, **options):
97        return NetworkSource(**options)
98
99    def create_rewrite_set_tag(self, tag, **options):
100        return SetTag(tag, **options)
101
102    def create_rewrite_set_pri(self, pri, **options):
103        return SetPri(pri, **options)
104
105    def create_filter(self, **options):
106        return Filter([], **options)
107
108    def create_app_parser(self, **options):
109        return Parser("app-parser", **options)
110
111    def create_checkpoint_parser(self, **options):
112        return Parser("checkpoint-parser", **options)
113
114    def create_panos_parser(self, **options):
115        return Parser("panos-parser", **options)
116
117    def create_regexp_parser(self, **options):
118        return Parser("regexp-parser", **options)
119
120    def create_syslog_parser(self, **options):
121        return Parser("syslog-parser", **options)
122
123    def create_file_destination(self, **options):
124        return FileDestination(**options)
125
126    def create_example_destination(self, **options):
127        return ExampleDestination(**options)
128
129    def create_snmp_destination(self, **options):
130        return SnmpDestination(**options)
131
132    def create_db_parser(self, config, **options):
133        return DBParser(config, **options)
134
135    def create_logpath(self, statements=None, flags=None):
136        logpath = self.__create_logpath_with_conversion(statements, flags)
137        self.__syslog_ng_config["logpath_groups"].append(logpath)
138        return logpath
139
140    def create_inner_logpath(self, statements=None, flags=None):
141        inner_logpath = self.__create_logpath_with_conversion(statements, flags)
142        return inner_logpath
143
144    def create_statement_group(self, statements):
145        statement_group = StatementGroup(statements)
146        self.__syslog_ng_config["statement_groups"].append(statement_group)
147        return statement_group
148
149    def __create_statement_group_if_needed(self, item):
150        if isinstance(item, (StatementGroup, LogPath)):
151            return item
152        else:
153            return self.create_statement_group(item)
154
155    def __create_logpath_with_conversion(self, items, flags):
156        return self.__create_logpath_group(
157            map(self.__create_statement_group_if_needed, cast_to_list(items)),
158            flags,
159        )
160
161    @staticmethod
162    def __create_logpath_group(statements=None, flags=None):
163        logpath = LogPath()
164        if statements:
165            logpath.add_groups(statements)
166        if flags:
167            logpath.add_flags(cast_to_list(flags))
168        return logpath
169