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 51SERVER_CLIENT_CA_PATH=/path/to/netdata-client-ca.pem 52""" 53 54 with open(".env.sample", 'w') as f: 55 f.write(env_content) 56 57 # Sample zuliprc file 58 zuliprc_content = """[api] 59site=https://yourorg.zulipchat.com 60email=netdata-bot@yourorg.zulipchat.com 61key=your-api-key-here 62stream=netdata-alerts 63""" 64 65 with open(".zuliprc.sample", 'w') as f: 66 f.write(zuliprc_content) 67 68 print("Created sample configuration files:") 69 print(" - .env.sample") 70 print(" - .zuliprc.sample") 71 print() 72 print("Copy and customize these files:") 73 print(" cp .env.sample .env") 74 print(" cp .zuliprc.sample ~/.zuliprc") 75 76 77def main(): 78 """Main entry point.""" 79 parser = argparse.ArgumentParser( 80 description="Netdata Zulip Bot - Webhook service for Netdata Cloud notifications" 81 ) 82 parser.add_argument( 83 "--zuliprc", 84 help="Path to zuliprc configuration file (default: ~/.zuliprc)" 85 ) 86 parser.add_argument( 87 "--create-config", 88 action="store_true", 89 help="Create sample configuration files and exit" 90 ) 91 parser.add_argument( 92 "--env-config", 93 action="store_true", 94 help="Use environment variables for configuration instead of zuliprc" 95 ) 96 97 args = parser.parse_args() 98 99 setup_logging() 100 logger = structlog.get_logger() 101 102 if args.create_config: 103 create_sample_configs() 104 return 105 106 try: 107 # Load configuration 108 if args.env_config: 109 zulip_config, server_config = load_config() 110 else: 111 zulip_config = load_zuliprc_config(args.zuliprc) 112 # Still need server config from environment 113 _, server_config = load_config() 114 115 # Create and start the webhook server 116 server = NetdataWebhookServer(zulip_config, server_config) 117 server.run() 118 119 except KeyboardInterrupt: 120 logger.info("Shutting down webhook server") 121 except Exception as e: 122 logger.error("Failed to start webhook server", error=str(e)) 123 sys.exit(1) 124 125 126if __name__ == "__main__": 127 main()