package main import ( "context" "errors" "fmt" "log" "os" "os/signal" "syscall" "time" "github.com/spf13/cobra" ) func devCmd(cmd *cobra.Command, args []string) { testDomain := "lunamc.org" //config, err = ezconf.LoadConfiguration("/etc/certman/certman.conf") err := LoadConfig("/etc/certman/certman.conf") if err != nil { log.Fatalf("Error loading configuration: %v\n", err) } err = LoadDomainConfigs() if err != nil { log.Fatalf("Error loading configs: %v\n", err) } fmt.Println(testDomain) } func versionCmd(cmd *cobra.Command, args []string) { fmt.Println("CertManager (certman) - Steven Tracey\nVersion: " + version + " build-" + build) } func newKeyCmd(cmd *cobra.Command, args []string) { key, err := GenerateKey() if err != nil { log.Fatalf("%v", err) } fmt.Printf(key) } func newDomain(domain, domainDir string, dirOverridden bool) error { //TODO add config option for "overriden dir" fmt.Printf("Creating new domain %s\n", domain) err := createNewDomainConfig(domain) if err != nil { return err } createNewDomainCertsDir(domain, domainDir, dirOverridden) fmt.Println("Successfully created domain entry for " + domain + "\nUpdate config file as needed in /etc/certman/domains/" + domainDir + ".conf") return nil } func install(isThin bool, mode string) error { if !isThin { makeDirs() } //config, err = ezconf.NewConfiguration(configFile, strings.ReplaceAll(defaultConfig, "{mode}", mode)) createNewConfig(mode) return nil } func runDaemonCmd() error { err := createOrUpdatePIDFile("/var/run/certman.pid") if err != nil { if errors.Is(err, ErrorPIDInUse) { return fmt.Errorf("daemon process is already running") } return fmt.Errorf("error creating pidfile: %v", err) } ctx, cancel = context.WithCancel(context.Background()) // Check if main config exists if _, err := os.Stat(configFile); os.IsNotExist(err) { return fmt.Errorf("main config file not found, please run 'certman --install', then properly configure /etc/certman/certman.conf") } else if err != nil { return fmt.Errorf("error opening %s: %v", configFile, err) } err = LoadConfig(configFile) if err != nil { return fmt.Errorf("error loading configuration: %v", err) } // Setup SIGINT and SIGTERM listeners sigChannel := make(chan os.Signal, 1) signal.Notify(sigChannel, syscall.SIGINT, syscall.SIGTERM) defer signal.Stop(sigChannel) reloadSigChan := make(chan os.Signal, 1) signal.Notify(reloadSigChan, syscall.SIGHUP) defer signal.Stop(reloadSigChan) tickRate := config.GetInt("App.tick_rate") ticker := time.NewTicker(time.Duration(tickRate) * time.Hour) defer ticker.Stop() wg.Add(1) if config.GetString("App.mode") == "server" { fmt.Println("Starting CertManager in server mode...") // Server Task loop go func() { initServer() defer wg.Done() for { select { case <-ctx.Done(): stopServer() return case <-reloadSigChan: reloadServer() case <-ticker.C: serverTick() } } }() } else if config.GetString("App.mode") == "client" { fmt.Println("Starting CertManager in client mode...") // Client Task loop go func() { initClient() defer wg.Done() for { select { case <-ctx.Done(): stopClient() return case <-reloadSigChan: reloadClient() case <-ticker.C: clientTick() } } }() } else { return fmt.Errorf("invalid operating mode \"" + config.GetString("App.mode") + "\"") } // Cleanup on stop sig := <-sigChannel fmt.Printf("Program terminated with %v\n", sig.String()) stop() wg.Wait() return nil } func stop() { cancel() clearPIDFile() } func stopDaemonCmd() error { proc, err := getDaemonProcess() if err != nil { return fmt.Errorf("error getting daemon process: %v", err) } err = proc.Signal(syscall.SIGTERM) if err != nil { return fmt.Errorf("error sending SIGTERM to daemon PID: %v", err) } return nil } func reloadDaemonCmd() error { proc, err := getDaemonProcess() if err != nil { return fmt.Errorf("error getting daemon process: %v", err) } err = proc.Signal(syscall.SIGHUP) if err != nil { return fmt.Errorf("error sending SIGHUP to daemon PID: %v", err) } return nil } func statusDaemonCmd() error { fmt.Println("Not implemented :/") return nil }