package main import ( "context" "fmt" "gitea.pena/PenaSide/common/validate" "gitea.pena/PenaSide/customer/internal/models" "github.com/caarlos0/env/v8" "github.com/gofiber/fiber/v2" "github.com/twmb/franz-go/pkg/kgo" "log" "time" ) func main() { config, err := loadConfig() if err != nil { log.Fatalf("error loading config: %v", err) } err = validateNotEmpty(config) if err != nil { log.Fatalf("error validating config: %v", err) } urls := []string{ config.AuthMicroserviceURL, config.HubadminMicroserviceURL, config.CurrencyMicroserviceURL, config.DiscountMicroserviceGRPC, config.CodewordMicroserviceGRPC, config.PaymentMicroserviceGRPC, config.VerificationMicroservice, config.TemplategenMicroserviceURL, config.TrashLogHost, config.AdminURL, config.ExternalCfg.MailClientCfg.ApiURL, } if err = validateURLs(urls); err != nil { log.Fatalf("error validating urls: %v", err) } // todo validate jwt if err = validateKafka(config.KafkaBrokers, config.KafkaTopicTariff); err != nil { log.Fatalf("error validating kafka: %v", err) } if err = validateMail(config.ExternalCfg.MailClientCfg); err != nil { log.Fatalf("error validating smtp: %v", err) } if err = validate.ValidateEncryptKeys(&config.ExternalCfg.EncryptCommon); err != nil { log.Fatalf("error validating encrypted: %v", err) } if err = validateTG(config.NotificationBotToken, config.NotificationRsPayChannel, config.NotificationChannel); err != nil { log.Fatalf("error validating tg enviroments: %v", err) } if err = validate.ValidateMongo(config.ExternalCfg.Database); err != nil { log.Fatalf("error validating mongodb: %v", err) } } // 38 fields func loadConfig() (*models.Config, error) { var config models.Config if err := env.Parse(&config); err != nil { return nil, err } return &config, nil } func validateURLs(urls []string) error { for index, u := range urls { if u == "" { return fmt.Errorf("empty url, index: %d", index) } // todo check the liveness of these URLs, many services do not support } return nil } func validateKafka(brokers []string, topic string) error { if len(brokers) == 0 { return fmt.Errorf("kafka brokers is empty") } if topic == "" { return fmt.Errorf("kafka topic is empty") } for _, addr := range brokers { if addr == "" { return fmt.Errorf("empty kafka broker") } } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() kafkaTariffClient, err := kgo.NewClient( kgo.SeedBrokers(brokers...), kgo.ConsumeResetOffset(kgo.NewOffset().AtStart()), kgo.DefaultProduceTopic(topic), kgo.ConsumeTopics(topic), ) if err != nil { return err } defer kafkaTariffClient.Close() err = kafkaTariffClient.Ping(ctx) if err != nil { return err } return nil } func validateMail(cfg models.MailClientCfg) error { if cfg.MailAddress == "" { return fmt.Errorf("mail address is empty") } if cfg.ApiURL == "" { return fmt.Errorf("mail api url is empty") } if cfg.ApiKey == "" { return fmt.Errorf("mail api key is empty") } if cfg.Sender == "" { return fmt.Errorf("mail sender is empty") } client := fiber.AcquireClient() req := client.Get("https://api.smtp.bz/v1/user") req.Set("Authorization", cfg.ApiKey) code, _, _ := req.Bytes() if code != fiber.StatusOK { return fmt.Errorf("invalid smtp code, no auth: %d", code) } return nil } func validateNotEmpty(config *models.Config) error { if config.ExternalCfg.EncryptCommon.PrivKey == "" { return fmt.Errorf("invalid private encrypt key") } if config.ExternalCfg.EncryptCommon.PubKey == "" { return fmt.Errorf("invalid publice encrypt key") } return nil } func validateTG(notificationBotToken string, notificationRsPayChannel int64, notificationChannel int64) error { err := validate.ValidateTgToken(notificationBotToken) if err != nil { return err } if notificationChannel == 0 { return fmt.Errorf("notificationChannel is not set") } if notificationRsPayChannel == 0 { return fmt.Errorf("notificationRsPayChannel is not set") } return nil }