Add templating, catch Exceptions and lowercase arguments
Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
parent
9b7919c5fe
commit
cbf5132b69
3 changed files with 77 additions and 45 deletions
20
README.md
20
README.md
|
@ -50,3 +50,23 @@ tail -f /var/log/nagios4/telegram.log
|
|||
```
|
||||
|
||||
Log level can be raised using `--verbose` or even more with `--debug` arguments.
|
||||
|
||||
|
||||
## Message format
|
||||
|
||||
`notify-by-telegram` script uses the `MarkdownV2` format to generate Telegram messages.
|
||||
|
||||
[Jinja](https://jinja.palletsprojects.com) is used for templating (eg. replace `{{host_name}}` placeholders by the value submitted by Nagios).
|
||||
|
||||
Default **host** and **service** templates can be found in the [templates](templates) directory.
|
||||
|
||||
They can be overriden in the configuration file:
|
||||
|
||||
```json
|
||||
{
|
||||
"host_template": "/etc/nagios4/host.md.j2",
|
||||
"service_template": "/etc/nagios4/service.md.j2"
|
||||
}
|
||||
```
|
||||
|
||||
Both options are optional.
|
||||
|
|
1
TODO.txt
1
TODO.txt
|
@ -1,4 +1,3 @@
|
|||
Add host and service templates to configuration file (+doc)
|
||||
Factorize the template rendering functions
|
||||
Use JSON schema to validate configuration file
|
||||
Add pre-commit Dockerfile and a doc to easily lint the code
|
||||
|
|
|
@ -18,32 +18,32 @@ def parse_arguments():
|
|||
parser = argparse.ArgumentParser()
|
||||
# base arguments
|
||||
parser.add_argument('-v', '--verbose', dest='loglevel', action='store_const', const=logging.INFO,
|
||||
help='Print more output')
|
||||
help='print more output')
|
||||
parser.add_argument('-d', '--debug', dest='loglevel', action='store_const', const=logging.DEBUG,
|
||||
default=logging.WARNING, help='Print even more output')
|
||||
parser.add_argument('-c', '--config', help='Configuration file location', required=True)
|
||||
parser.add_argument('-o', '--logfile', help='Logging file location')
|
||||
subparsers = parser.add_subparsers(title='commands', dest='command', help='Nagios notification type')
|
||||
default=logging.WARNING, help='print even more output')
|
||||
parser.add_argument('-c', '--config', help='configuration file location', required=True)
|
||||
parser.add_argument('-o', '--logfile', help='logging file location')
|
||||
subparsers = parser.add_subparsers(title='commands', dest='command', help='nagios notification type')
|
||||
|
||||
# host notifications
|
||||
host_parser = subparsers.add_parser('host')
|
||||
host_parser.add_argument('--notification-type', help='Nagios $NOTIFICATIONTYPE$', required=True)
|
||||
host_parser.add_argument('--service-desc', help='Nagios $SERVICEDESC$', required=True)
|
||||
host_parser.add_argument('--host-name', help='Nagios $HOSTNAME$', required=True)
|
||||
host_parser.add_argument('--host-state', help='Nagios $HOSTSTATE$', required=True)
|
||||
host_parser.add_argument('--host-address', help='Nagios $HOSTADDRESS$', required=True)
|
||||
host_parser.add_argument('--host-output', help='Nagios $HOSTOUTPUT$', required=True)
|
||||
host_parser.add_argument('--long-date-time', help='Nagios $LONGDATETIME$', required=True)
|
||||
host_parser.add_argument('--notification-type', help='nagios $NOTIFICATIONTYPE$', required=True)
|
||||
host_parser.add_argument('--service-desc', help='nagios $SERVICEDESC$', required=True)
|
||||
host_parser.add_argument('--host-name', help='nagios $HOSTNAME$', required=True)
|
||||
host_parser.add_argument('--host-state', help='nagios $HOSTSTATE$', required=True)
|
||||
host_parser.add_argument('--host-address', help='nagios $HOSTADDRESS$', required=True)
|
||||
host_parser.add_argument('--host-output', help='nagios $HOSTOUTPUT$', required=True)
|
||||
host_parser.add_argument('--long-date-time', help='nagios $LONGDATETIME$', required=True)
|
||||
|
||||
# service notifications
|
||||
service_parser = subparsers.add_parser('service')
|
||||
service_parser.add_argument('--notification-type', help='Nagios $NOTIFICATIONTYPE$', required=True)
|
||||
service_parser.add_argument('--service-desc', help='Nagios $SERVICEDESC$', required=True)
|
||||
service_parser.add_argument('--host-alias', help='Nagios $HOSTALIAS$', required=True)
|
||||
service_parser.add_argument('--host-address', help='Nagios $HOSTADDRESS$', required=True)
|
||||
service_parser.add_argument('--service-state', help='Nagios $SERVICESTATE$', required=True)
|
||||
service_parser.add_argument('--long-date-time', help='Nagios $LONGDATETIME$', required=True)
|
||||
service_parser.add_argument('--service-output', help='Nagios $SERVICEOUTPUT$', required=True)
|
||||
service_parser.add_argument('--notification-type', help='nagios $NOTIFICATIONTYPE$', required=True)
|
||||
service_parser.add_argument('--service-desc', help='nagios $SERVICEDESC$', required=True)
|
||||
service_parser.add_argument('--host-alias', help='nagios $HOSTALIAS$', required=True)
|
||||
service_parser.add_argument('--host-address', help='nagios $HOSTADDRESS$', required=True)
|
||||
service_parser.add_argument('--service-state', help='nagios $SERVICESTATE$', required=True)
|
||||
service_parser.add_argument('--long-date-time', help='nagios $LONGDATETIME$', required=True)
|
||||
service_parser.add_argument('--service-output', help='nagios $SERVICEOUTPUT$', required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
@ -59,10 +59,10 @@ def read_config(filename=None):
|
|||
|
||||
def validate_config(config):
|
||||
if config is None:
|
||||
raise InvalidConfigException('Config is not a dict')
|
||||
raise InvalidConfigException('config is not a dict')
|
||||
for key in ['chat_id', 'auth_key']:
|
||||
if key not in config:
|
||||
raise InvalidConfigException(f'Missing "{key}" key in config')
|
||||
raise InvalidConfigException(f'missing "{key}" key in config')
|
||||
|
||||
|
||||
def setup_logging(args):
|
||||
|
@ -76,12 +76,16 @@ def markdown_escape(text):
|
|||
return text
|
||||
|
||||
|
||||
def generate_host_payload(chat_id, args):
|
||||
def generate_host_payload(chat_id, args, template_file_name=None):
|
||||
payload = {'chat_id': chat_id, 'parse_mode': 'MarkdownV2'}
|
||||
absolute_path = os.path.split(os.path.abspath(__file__))[0]
|
||||
loader = FileSystemLoader(os.path.join(absolute_path, 'templates'))
|
||||
if not template_file_name:
|
||||
absolute_path = os.path.split(os.path.abspath(__file__))[0]
|
||||
template_file_name = os.path.join(absolute_path, 'templates', 'host.md.j2')
|
||||
template_path = os.path.dirname(os.path.abspath(template_file_name))
|
||||
template_name = os.path.basename(os.path.abspath(template_file_name))
|
||||
loader = FileSystemLoader(template_path)
|
||||
env = Environment(loader=loader)
|
||||
template = env.get_template('host.md.j2')
|
||||
template = env.get_template(template_name)
|
||||
text = template.render(notification_type=markdown_escape(args.notification_type),
|
||||
host_name=markdown_escape(args.host_name), host_state=markdown_escape(args.host_state),
|
||||
host_address=markdown_escape(args.host_address),
|
||||
|
@ -91,12 +95,16 @@ def generate_host_payload(chat_id, args):
|
|||
return payload
|
||||
|
||||
|
||||
def generate_service_payload(chat_id, args):
|
||||
def generate_service_payload(chat_id, args, template_file_name=None):
|
||||
payload = {'chat_id': chat_id, 'parse_mode': 'MarkdownV2'}
|
||||
absolute_path = os.path.split(os.path.abspath(__file__))[0]
|
||||
loader = FileSystemLoader(os.path.join(absolute_path, 'templates'))
|
||||
if not template_file_name:
|
||||
absolute_path = os.path.split(os.path.abspath(__file__))[0]
|
||||
template_file_name = os.path.join(absolute_path, 'templates', 'service.md.j2')
|
||||
template_path = os.path.dirname(os.path.abspath(template_file_name))
|
||||
template_name = os.path.basename(os.path.abspath(template_file_name))
|
||||
loader = FileSystemLoader(template_path)
|
||||
env = Environment(loader=loader)
|
||||
template = env.get_template('service.md.j2')
|
||||
template = env.get_template(template_name)
|
||||
text = template.render(notification_type=markdown_escape(args.notification_type),
|
||||
service_desc=markdown_escape(args.service_desc), host_alias=markdown_escape(args.host_alias),
|
||||
host_address=markdown_escape(args.host_address),
|
||||
|
@ -116,23 +124,28 @@ def send_message(auth_key, payload):
|
|||
|
||||
|
||||
def main():
|
||||
args = parse_arguments()
|
||||
setup_logging(args)
|
||||
logger.info(f'reading configuration file {args.config}')
|
||||
config = read_config(args.config)
|
||||
logger.info('validating configuration')
|
||||
validate_config(config)
|
||||
try:
|
||||
args = parse_arguments()
|
||||
setup_logging(args)
|
||||
logger.info(f'reading configuration file {args.config}')
|
||||
config = read_config(args.config)
|
||||
logger.info('validating configuration')
|
||||
validate_config(config)
|
||||
|
||||
logger.info('generating payload')
|
||||
if args.command == 'host':
|
||||
payload = generate_host_payload(chat_id=config['chat_id'], args=args)
|
||||
elif args.command == 'service':
|
||||
payload = generate_service_payload(chat_id=config['chat_id'], args=args)
|
||||
else:
|
||||
raise NotImplementedError(f'Command {args.command} not supported')
|
||||
logger.info('generating payload')
|
||||
if args.command == 'host':
|
||||
payload = generate_host_payload(chat_id=config['chat_id'], args=args,
|
||||
template_file_name=config.get('host_template'))
|
||||
elif args.command == 'service':
|
||||
payload = generate_service_payload(chat_id=config['chat_id'], args=args,
|
||||
template_file_name=config.get('service_template'))
|
||||
else:
|
||||
raise NotImplementedError(f'command {args.command} not supported')
|
||||
|
||||
logger.info('sending message to telegram api')
|
||||
send_message(auth_key=config['auth_key'], payload=payload)
|
||||
logger.info('sending message to telegram api')
|
||||
send_message(auth_key=config['auth_key'], payload=payload)
|
||||
except Exception as err:
|
||||
logger.exception('cannot execute program')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in a new issue