Netdata.cloud bot for Zulip
1"""Main entry point for the Netdata Zulip bot.""" 2 3import argparse 4import sys 5from pathlib import Path 6 7import structlog 8 9from .config import load_config, load_zuliprc_config 10from .models import ServerConfig 11from .server import NetdataWebhookServer 12 13 14def setup_logging(): 15 """Configure structured logging.""" 16 structlog.configure( 17 processors=[ 18 structlog.stdlib.filter_by_level, 19 structlog.stdlib.add_logger_name, 20 structlog.stdlib.add_log_level, 21 structlog.stdlib.PositionalArgumentsFormatter(), 22 structlog.processors.TimeStamper(fmt="iso"), 23 structlog.processors.StackInfoRenderer(), 24 structlog.processors.format_exc_info, 25 structlog.processors.UnicodeDecoder(), 26 structlog.processors.JSONRenderer() 27 ], 28 context_class=dict, 29 logger_factory=structlog.stdlib.LoggerFactory(), 30 wrapper_class=structlog.stdlib.BoundLogger, 31 cache_logger_on_first_use=True, 32 ) 33 34 35def create_sample_configs(): 36 """Create sample configuration files.""" 37 38 # Sample .env file 39 env_content = """# Zulip Configuration 40ZULIP_SITE=https://yourorg.zulipchat.com 41ZULIP_EMAIL=netdata-bot@yourorg.zulipchat.com 42ZULIP_API_KEY=your-api-key-here 43ZULIP_STREAM=netdata-alerts 44 45# Server Configuration 46SERVER_HOST=0.0.0.0 47SERVER_PORT=8443 48SERVER_DOMAIN=your-domain.com 49SERVER_CERT_PATH=/etc/letsencrypt/live 50SERVER_ENABLE_MTLS=true 51""" 52 53 with open(".env.sample", 'w') as f: 54 f.write(env_content) 55 56 # Sample zuliprc file 57 zuliprc_content = """[api] 58site=https://yourorg.zulipchat.com 59email=netdata-bot@yourorg.zulipchat.com 60key=your-api-key-here 61stream=netdata-alerts 62""" 63 64 with open(".zuliprc.sample", 'w') as f: 65 f.write(zuliprc_content) 66 67 print("Created sample configuration files:") 68 print(" - .env.sample") 69 print(" - .zuliprc.sample") 70 print() 71 print("Copy and customize these files:") 72 print(" cp .env.sample .env") 73 print(" cp .zuliprc.sample ~/.zuliprc") 74 75 76def main(): 77 """Main entry point.""" 78 parser = argparse.ArgumentParser( 79 description="Netdata Zulip Bot - Webhook service for Netdata Cloud notifications" 80 ) 81 parser.add_argument( 82 "--zuliprc", 83 help="Path to zuliprc configuration file (default: ~/.zuliprc)" 84 ) 85 parser.add_argument( 86 "--create-config", 87 action="store_true", 88 help="Create sample configuration files and exit" 89 ) 90 parser.add_argument( 91 "--env-config", 92 action="store_true", 93 help="Use environment variables for configuration instead of zuliprc" 94 ) 95 96 args = parser.parse_args() 97 98 setup_logging() 99 logger = structlog.get_logger() 100 101 if args.create_config: 102 create_sample_configs() 103 return 104 105 try: 106 # Load configuration 107 if args.env_config: 108 zulip_config, server_config = load_config() 109 else: 110 zulip_config = load_zuliprc_config(args.zuliprc) 111 # Still need server config from environment 112 _, server_config = load_config() 113 114 # Create and start the webhook server 115 server = NetdataWebhookServer(zulip_config, server_config) 116 server.run() 117 118 except KeyboardInterrupt: 119 logger.info("Shutting down webhook server") 120 except Exception as e: 121 logger.error("Failed to start webhook server", error=str(e)) 122 sys.exit(1) 123 124 125if __name__ == "__main__": 126 main()