diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/certmgr b/certmgr new file mode 100644 index 0000000..8b15b32 Binary files /dev/null and b/certmgr differ diff --git a/main.go b/main.go index d793d4f..b4e4dbc 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,16 @@ import ( "code.gitea.io/sdk/gitea" "fmt" "git.nevets.tech/Steven/ezconf" + "github.com/go-git/go-git/v5/plumbing/object" "os/exec" + "strings" + "time" - "github.com/go-git/go-billy/v5" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/go-git/go-git/v5/storage/memory" + billy "github.com/go-git/go-billy/v5" + memfs "github.com/go-git/go-billy/v5/memfs" + git "github.com/go-git/go-git/v5" + http "github.com/go-git/go-git/v5/plumbing/transport/http" + memory "github.com/go-git/go-git/v5/storage/memory" "os" ) @@ -34,7 +38,7 @@ func main() { if hasConfig { config = ezconf.NewConfiguration(args[configIndex+1]) } else { - fmt.Printf("Error, no config passed. Please add '-c /path/to/config.ini' to the command") + fmt.Printf("Error, no config passed. Please add '-c /path/to/config.ini' to the command\n") os.Exit(1) } @@ -43,7 +47,7 @@ func main() { if hasDomain { domain = args[domainIndex+1] } else { - fmt.Printf("Error, no domain passed. Please add '-d domain.tld' to the command") + fmt.Printf("Error, no domain passed. Please add '-d domain.tld' to the command\n") os.Exit(1) } @@ -69,7 +73,7 @@ func main() { err = os.Setenv("CF_API_TOKEN", config.GetAsString("Cloudflare.cf_api_token")) err = os.Setenv("CF_EMAIL", config.GetAsString("Cloudflare.cf_email")) if err != nil { - fmt.Printf("Error setting environment variable: %v", err) + fmt.Printf("Error setting environment variable: %v\n", err) os.Exit(1) } @@ -77,23 +81,28 @@ func main() { Username: config.GetAsString("Git.username"), Password: config.GetAsString("Git.api_token"), } - giteaClient, err = gitea.NewClient(config.GetAsString("Git.server"), gitea.SetBasicAuth(config.GetAsString("Git.username"), config.GetAsString("Git.api_token"))) + giteaClient, err = gitea.NewClient(config.GetAsString("Git.server"), gitea.SetToken(config.GetAsString("Git.api_token"))) if err != nil { - fmt.Printf("Error connecting to gitea instance: %v", err) + fmt.Printf("Error connecting to gitea instance: %v\n", err) os.Exit(1) } + storage = memory.NewStorage() + fs = memfs.New() + + var cmd *exec.Cmd switch args[len(args)-1] { case "gen": { url := createGiteaRepo() cloneRepo(url) - exec.Command("lego", legoNewSiteArgs...) + fixUpdateSh() + cmd = exec.Command("lego", legoNewSiteArgs...) } case "renew": { cloneRepo(config.GetAsString("Git.server") + "/" + config.GetAsString("Git.org_name")) - exec.Command("lego", legoRenewSiteArgs...) + cmd = exec.Command("lego", legoRenewSiteArgs...) } default: { @@ -101,18 +110,32 @@ func main() { os.Exit(1) } } + fmt.Printf("Env Vars: %v", cmd.Env) + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Printf("Error creating certs with lego: %v", err) + os.Exit(1) + } + fmt.Println(string(out)) + addAndPushCerts() } func createGiteaRepo() string { options := gitea.CreateRepoFromTemplateOption{ - Owner: config.GetAsString("Git.repo_owner"), - Name: domain + "-certificates", + Avatar: true, Description: "Certificates storage for " + domain, + GitContent: true, + GitHooks: true, + Labels: true, + Name: domain + "-certificates", + Owner: config.GetAsString("Git.org_name"), Private: true, + Topics: true, + Webhooks: true, } giteaRepo, _, err := giteaClient.CreateRepoFromTemplate(config.GetAsString("Git.org_name"), config.GetAsString("Git.template_name"), options) if err != nil { - fmt.Printf("Error creating repo: %v", err) + fmt.Printf("Error creating repo: %v\n", err) os.Exit(1) } return giteaRepo.CloneURL @@ -122,35 +145,84 @@ func cloneRepo(url string) { var err error repo, err = git.Clone(storage, fs, &git.CloneOptions{URL: url, Auth: creds}) if err != nil { - fmt.Printf("Error clone git repo: %v", err) + fmt.Printf("Error clone git repo: %v\n", err) os.Exit(1) } workTree, err = repo.Worktree() if err != nil { - fmt.Printf("Error getting worktree from repo: %v", err) + fmt.Printf("Error getting worktree from repo: %v\n", err) + os.Exit(1) + } +} + +func fixUpdateSh() { + updateSh, err := fs.Open("update.sh") + if err != nil { + fmt.Printf("Error opening update.sh: %v", err) + os.Exit(1) + } + content := "#!/bin/env bash\necho Starting cert pull\ngit pull https://Steven:07026d2d4e99614ec98fc2a8357f108f78f52682@git.nevets.tech/Keys/" + domain + "-certificates.git --force --no-rebase\nexit 0" + fmt.Printf("Update.sh Content: %v\n", content) + _, err = updateSh.Write([]byte(content)) + err = updateSh.Close() + if err != nil { + fmt.Printf("Error writing update.sh: %v", err) os.Exit(1) } } func addAndPushCerts() { - // Copy certs to memfs - - //file, err := fs.Create("") - //if err != nil { - // return - //} - _, err = workTree.Add(domain + "*") + //TODO integrate SOPS api when stable release + certs, err := os.ReadDir(config.GetAsString("Certificates.certs_path")) if err != nil { - fmt.Printf("Error adding certificates to workTree: %v", err) + fmt.Printf("Error reading from directory: %v\n", err) + os.Exit(1) + } + for _, cert := range certs { + if strings.HasPrefix(cert.Name(), domain) { + file, err := fs.Create(config.GetAsString("Certificates.certs_path" + "/" + cert.Name())) + if err != nil { + fmt.Printf("Error copying cert to memfs: %v\n", err) + os.Exit(1) + } + certFile, err := os.ReadFile(config.GetAsString("Certificates.certs_path" + "/" + cert.Name())) + _, err = file.Write(certFile) + if err != nil { + fmt.Printf("Error writing to memfs: %v\n", err) + os.Exit(1) + } + } + } + + _, err = workTree.Add(".") + if err != nil { + fmt.Printf("Error adding certificates to workTree: %v\n", err) os.Exit(1) } status, err := workTree.Status() if err != nil { - fmt.Printf("Error getting repo status: %v", err) + fmt.Printf("Error getting repo status: %v\n", err) os.Exit(1) } fmt.Println(status.String()) + signature := &object.Signature{ + Name: "Cert Manager", + Email: "certs@nevets.tech", + When: time.Now(), + } + _, err = workTree.Commit("Update "+domain+" @ "+time.Now().String(), &git.CommitOptions{Author: signature, Committer: signature}) + if err != nil { + fmt.Printf("Error committing certs: %v\n", err) + os.Exit(1) + } + err = repo.Push(&git.PushOptions{Auth: creds, Force: true, RemoteName: "origin"}) + if err != nil { + fmt.Printf("Error pushing to origin: %v\n", err) + os.Exit(1) + } + + fmt.Println("Successfully uploaded to repo") } func contains(slice []string, value string) (sliceHas bool, index int) {