package server import ( "fmt" "path/filepath" "time" "git.nevets.tech/Steven/certman/app/shared" "git.nevets.tech/Steven/certman/common" "git.nevets.tech/Steven/certman/server" "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5/storage/memory" "github.com/spf13/cobra" ) var ( noPush bool renewCertSubCmd = &cobra.Command{ Use: "renew", Short: "Renews a domains certificate", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { return renewCertCmd(args[0], noPush) }, } ) func init() { renewCertSubCmd.Flags().BoolVar(&noPush, "no-push", false, "Don't push certs to repo, renew locally only [server mode only]") shared.CertCmd.AddCommand(renewCertSubCmd) } func renewCertCmd(domain string, noPush bool) error { if err := shared.LoadConfig(); err != nil { return err } if err := shared.LoadDomainConfigs(); err != nil { return err } mgr, err := server.NewACMEManager(shared.Config()) if err != nil { return err } err = renewCerts(domain, noPush, mgr) if err != nil { return err } // return ReloadDaemonCmd() // Not sure if this is necessary return nil } func renewCerts(domain string, noPush bool, mgr *server.ACMEManager) error { config := shared.Config() domainConfig, exists := shared.DomainStore().Get(domain) if !exists { return fmt.Errorf("domain %s does not exist", domain) } _, err := mgr.RenewForDomain(domain) if err != nil { // if no existing cert, obtain instead _, err = mgr.ObtainForDomain(domain, config, domainConfig) if err != nil { return fmt.Errorf("error obtaining domain certificates for domain %s: %v", domain, err) } } domainConfig.Internal.LastIssued = time.Now().UTC().Unix() err = shared.WriteDomainConfig(domainConfig) if err != nil { return fmt.Errorf("error saving domain config %s: %v", domain, err) } err = common.EncryptFileXChaCha(domainConfig.Certificates.CryptoKey, filepath.Join(mgr.CertsRoot, domain, domain+".crt"), filepath.Join(mgr.CertsRoot, domain, domain+".crt.crpt"), nil) if err != nil { return fmt.Errorf("error encrypting domain cert for domain %s: %v", domain, err) } err = common.EncryptFileXChaCha(domainConfig.Certificates.CryptoKey, filepath.Join(mgr.CertsRoot, domain, domain+".key"), filepath.Join(mgr.CertsRoot, domain, domain+".key.crpt"), nil) if err != nil { return fmt.Errorf("error encrypting domain key for domain %s: %v", domain, err) } if !noPush { giteaClient := common.CreateGiteaClient(config) if giteaClient == nil { return fmt.Errorf("error creating gitea client for domain %s: %v", domain, err) } gitWorkspace := &common.GitWorkspace{ Storage: memory.NewStorage(), FS: memfs.New(), } var repoUrl string if !domainConfig.Internal.RepoExists { repoUrl = common.CreateGiteaRepo(domain, giteaClient, config, domainConfig) if repoUrl == "" { return fmt.Errorf("error creating Gitea repo for domain %s", domain) } domainConfig.Internal.RepoExists = true err = shared.WriteDomainConfig(domainConfig) if err != nil { return fmt.Errorf("error saving domain config %s: %v", domain, err) } err = common.InitRepo(repoUrl, gitWorkspace) if err != nil { return fmt.Errorf("error initializing repo for domain %s: %v", domain, err) } } else { repoUrl = config.Git.Server + "/" + config.Git.OrgName + "/" + domain + domainConfig.Repo.RepoSuffix + ".git" err = common.CloneRepo(repoUrl, gitWorkspace, common.Server, config) if err != nil { return fmt.Errorf("error cloning repo for domain %s: %v", domain, err) } } err = common.AddAndPushCerts(domain, gitWorkspace, config, domainConfig) if err != nil { return fmt.Errorf("error pushing certificates for domain %s: %v", domain, err) } fmt.Printf("Successfully pushed certificates for domain %s\n", domain) } return nil }