1 Commits

Author SHA1 Message Date
c01195643a Lets see if this works
All checks were successful
Build (artifact) / build (push) Successful in 1m13s
2026-06-29 07:57:03 -04:00
13 changed files with 112 additions and 54 deletions

View File

@@ -44,7 +44,7 @@ jobs:
run: echo "COMMIT_MSG=$(git log -1 --pretty=%s)" >> $GITHUB_ENV
- name: Build
run: make build
run: make client server
- name: Upload artifact
uses: https://github.com/actions/upload-artifact@v3

View File

@@ -1,4 +1,4 @@
VERSION := 1.1.5-beta
VERSION := 1.1.6-beta
BUILD := $(shell git rev-parse --short HEAD)
GO := go
@@ -6,7 +6,7 @@ GO := go
BUILD_FLAGS := -buildmode=pie -trimpath
LDFLAGS := -linkmode=external -extldflags="-Wl,-z,relro,-z,now" -X git.nevets.tech/Keys/certman/common.Version=$(VERSION) -X git.nevets.tech/Keys/certman/common.Build=$(BUILD)
.PHONY: proto bundle client server executor build debug stage
.PHONY: proto bundle client server executor build debug stage help
proto:
@protoc --go_out=./proto --go-grpc_out=./proto proto/hook.proto
@@ -38,3 +38,13 @@ debug: proto
stage: build
@sudo cp ./certman /srv/vm-passthru/certman
@ssh steven@192.168.122.44 updateCertman.sh
help:
@echo "proto - Generate gRPC proto stubs"
@echo "bundle - Build bundled binary (client, server, executor)"
@echo "client - Build client binary"
@echo "server - Build server binary"
@echo "executor - Build executor binary"
@echo "build - Build all binaries"
@echo "debug - Build bundled binary without stripping and hardening"
@echo "stage - Build all binaries and upload to dev environment (vm)"

View File

@@ -30,3 +30,6 @@ sudo certman new-domain example.com
## Scratch Board
- Server Flow
- Read from
# Coding Conventions
- Keep Config() calls in app space

View File

@@ -47,17 +47,19 @@ func init() {
}
func renewCert(domain string) error {
gitWorkspace := &common.GitWorkspace{
Domain: domain,
Storage: memory.NewStorage(),
FS: memfs.New(),
}
config := app.Config()
domainConfig, exists := app.DomainStore().Get(domain)
if !exists {
return app.ErrConfigNotFound
}
if err := client.PullCerts(config, domainConfig, gitWorkspace); err != nil {
gitWorkspace := &common.GitWorkspace{
Domain: domain,
URL: config.Git.Server + "/" + config.Git.OrgName + "/" + domain + domainConfig.Repo.RepoSuffix + ".git",
Storage: memory.NewStorage(),
FS: memfs.New(),
}
if err := client.PullCerts(config, gitWorkspace); err != nil {
return err
}
certsDir := common.EffectiveDataRoot(config, domainConfig)

View File

@@ -67,13 +67,14 @@ func (d *Daemon) Tick() {
}
gitWorkspace := &common.GitWorkspace{
Domain: domainStr,
URL: app.Config().Git.Server + "/" + config.Git.OrgName + "/" + domainStr + domainConfig.Repo.RepoSuffix + ".git",
Storage: memory.NewStorage(),
FS: memfs.New(),
}
// Ex: https://git.example.com/Org/Repo-suffix.git
// Clones repo and stores in gitWorkspace, skip if clone fails (doesn't exist?)
repoUrl := app.Config().Git.Server + "/" + config.Git.OrgName + "/" + domainStr + domainConfig.Repo.RepoSuffix + ".git"
err := common.CloneRepo(repoUrl, gitWorkspace, common.Client, config)
err := gitWorkspace.CloneRepo(common.Client, config)
if err != nil {
fmt.Printf("Error cloning domain repo %s: %v\n", domainStr, err)
continue
@@ -121,7 +122,8 @@ func (d *Daemon) Tick() {
continue
}
err = common.WriteCommitHash(headRef.Hash().String(), config, domainConfig)
dataRoot := common.EffectiveDataRoot(config, domainConfig)
err = client.WriteCommitHash(headRef.Hash().String(), dataRoot)
if err != nil {
fmt.Printf("Error writing commit hash: %v\n", err)
continue

View File

@@ -55,17 +55,17 @@ func init() {
}
func devCmd(cmd *cobra.Command, args []string) {
testDomain := "lunamc.org"
err := LoadConfig()
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)
//testDomain := "lunamc.org"
//err := LoadConfig()
//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) {

View File

@@ -90,10 +90,9 @@ func renewCerts(domain string, noPush bool, mgr *server.ACMEManager) error {
FS: memfs.New(),
}
var repoUrl string
if !domainConfig.Internal.RepoExists {
repoUrl = common.CreateGiteaRepo(domain, giteaClient, config, domainConfig)
if repoUrl == "" {
gitWorkspace.URL = common.CreateGiteaRepo(domain, giteaClient, config, domainConfig)
if gitWorkspace.URL == "" {
return fmt.Errorf("error creating Gitea repo for domain %s", domain)
}
domainConfig.Internal.RepoExists = true
@@ -102,19 +101,20 @@ func renewCerts(domain string, noPush bool, mgr *server.ACMEManager) error {
return fmt.Errorf("error saving domain config %s: %v", domain, err)
}
err = common.InitRepo(repoUrl, gitWorkspace)
err = gitWorkspace.InitRepo()
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)
gitWorkspace.URL = config.Git.Server + "/" + config.Git.OrgName + "/" + domain + domainConfig.Repo.RepoSuffix + ".git"
err = gitWorkspace.CloneRepo(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)
dataRoot := common.EffectiveDataRoot(config, domainConfig)
err = server.AddAndPushCerts(gitWorkspace, dataRoot, domainConfig.Repo.RepoSuffix, config)
if err != nil {
return fmt.Errorf("error pushing certificates for domain %s: %v", domain, err)
}

View File

@@ -113,10 +113,9 @@ func (d *Daemon) Tick() {
FS: memfs.New(),
}
var repoUrl string
if !domainConfig.Internal.RepoExists {
repoUrl = common.CreateGiteaRepo(domainStr, giteaClient, config, domainConfig)
if repoUrl == "" {
gitWorkspace.URL = common.CreateGiteaRepo(domainStr, giteaClient, config, domainConfig)
if gitWorkspace.URL == "" {
fmt.Printf("Error creating Gitea repo for domain %s\n", domainStr)
continue
}
@@ -127,21 +126,22 @@ func (d *Daemon) Tick() {
continue
}
err = common.InitRepo(repoUrl, gitWorkspace)
err = gitWorkspace.InitRepo()
if err != nil {
fmt.Printf("Error initializing repo for domain %s: %v\n", domainStr, err)
continue
}
} else {
repoUrl = appShared.Config().Git.Server + "/" + appShared.Config().Git.OrgName + "/" + domainStr + domainConfig.Repo.RepoSuffix + ".git"
err = common.CloneRepo(repoUrl, gitWorkspace, common.Server, config)
gitWorkspace.URL = appShared.Config().Git.Server + "/" + appShared.Config().Git.OrgName + "/" + domainStr + domainConfig.Repo.RepoSuffix + ".git"
err = gitWorkspace.CloneRepo(common.Server, config)
if err != nil {
fmt.Printf("Error cloning repo for domain %s: %v\n", domainStr, err)
continue
}
}
err = common.AddAndPushCerts(domainStr, gitWorkspace, config, domainConfig)
dataRoot := common.EffectiveDataRoot(config, domainConfig)
err = server.AddAndPushCerts(gitWorkspace, dataRoot, domainConfig.Repo.RepoSuffix, config)
if err != nil {
fmt.Printf("Error pushing certificates for domain %s: %v\n", domainStr, err)
continue

View File

@@ -1,7 +1,37 @@
package main
import "fmt"
import (
"fmt"
"os"
"git.nevets.tech/Steven/certman/app"
"github.com/spf13/cobra"
)
func main() {
fmt.Println("Hello server")
rootCmd := &cobra.Command{
Use: "certman",
Short: "CertMan",
Long: "Certificate Manager",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}
rootCmd.AddCommand(app.VersionCmd)
rootCmd.AddCommand(app.NewKeyCmd)
rootCmd.AddCommand(app.DevCmd)
rootCmd.AddCommand(app.NewDomainCmd)
//-----------------------------------
rootCmd.AddCommand(app.InstallCmd)
rootCmd.AddCommand(app.CertCmd)
rootCmd.AddCommand(app.DaemonCmd)
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

View File

@@ -10,11 +10,10 @@ import (
"git.nevets.tech/Steven/certman/common"
)
func PullCerts(config *common.AppConfig, domainConfig *common.DomainConfig, gitWorkspace *common.GitWorkspace) error {
func PullCerts(config *common.AppConfig, gitWorkspace *common.GitWorkspace) error {
// Ex: https://git.example.com/Org/Repo-suffix.git
// Clones repo and stores in gitWorkspace, skip if clone fails (doesn't exist?)
repoUrl := config.Git.Server + "/" + config.Git.OrgName + "/" + gitWorkspace.Domain + domainConfig.Repo.RepoSuffix + ".git"
err := common.CloneRepo(repoUrl, gitWorkspace, common.Client, config)
err := gitWorkspace.CloneRepo(common.Client, config)
if err != nil {
return fmt.Errorf("Error cloning domain repo %s: %v\n", gitWorkspace.Domain, err)
}
@@ -60,7 +59,8 @@ func DecryptAndWriteCertificates(certsDir string, config *common.AppConfig, doma
continue
}
err = common.WriteCommitHash(headRef.Hash().String(), config, domainConfig)
dataRoot := common.EffectiveDataRoot(config, domainConfig)
err = WriteCommitHash(headRef.Hash().String(), dataRoot)
if err != nil {
fmt.Printf("Error writing commit hash: %v\n", err)
continue

View File

@@ -143,7 +143,7 @@ func NewACMEManager(config *common.AppConfig) (*ACMEManager, error) {
return nil, fmt.Errorf("cloudflare dns provider: %w", err)
}
if err := client.Challenge.SetDNS01Provider(cfProvider); err != nil {
if err = client.Challenge.SetDNS01Provider(cfProvider); err != nil {
return nil, fmt.Errorf("set dns-01 provider: %w", err)
}
@@ -159,7 +159,7 @@ func NewACMEManager(config *common.AppConfig) (*ACMEManager, error) {
return nil, fmt.Errorf("acme registration: %w", err)
}
mgr.User.Registration = reg
if err := saveACMEUser(mgr.accountRoot, mgr.User); err != nil {
if err = saveACMEUser(mgr.accountRoot, mgr.User); err != nil {
return nil, fmt.Errorf("save acme User registration: %w", err)
}
}
@@ -270,6 +270,7 @@ func buildDomainRuntimeConfig(config *common.AppConfig, domainConfig *common.Dom
// If a subdomain entry looks like a full FQDN already, it is used as-is.
func buildDomainList(baseDomain string, subs []string) []string {
seen := map[string]struct{}{}
out := make([]string, 0, len(subs)+1)
add := func(d string) {
d = strings.TrimSpace(strings.ToLower(d))
if d == "" {
@@ -279,6 +280,7 @@ func buildDomainList(baseDomain string, subs []string) []string {
return
}
seen[d] = struct{}{}
out = append(out, d)
}
add(baseDomain)
@@ -310,10 +312,6 @@ func buildDomainList(baseDomain string, subs []string) []string {
add(s + "." + baseDomain)
}
out := make([]string, 0, len(seen))
for d := range seen {
out = append(out, d)
}
return out
}

View File

@@ -0,0 +1,15 @@
package server
import (
"fmt"
"slices"
"testing"
)
func TestBuildDomainList(t *testing.T) {
domains := buildDomainList("example.com", []string{"*", "dev"})
fmt.Printf("domains: %v\n", domains)
if slices.Compare(domains, []string{"example.com", "*.example.com", "dev.example.com"}) != 0 {
t.Errorf("domains not equal")
}
}

View File

@@ -14,9 +14,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/transport/http"
)
type GitWorkspace common.GitWorkspace
func (ws *GitWorkspace) AddAndPushCerts(dataRoot, repoSuffix string, config *common.AppConfig) error {
func AddAndPushCerts(ws *common.GitWorkspace, dataRoot, repoSuffix string, config *common.AppConfig) error {
certFiles, err := os.ReadDir(dataRoot)
if err != nil {
fmt.Printf("Error reading from directory: %v\n", err)