Lets see if this works
All checks were successful
Build (artifact) / build (push) Successful in 1m13s
All checks were successful
Build (artifact) / build (push) Successful in 1m13s
This commit is contained in:
@@ -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
|
||||
|
||||
14
Makefile
14
Makefile
@@ -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)"
|
||||
@@ -30,3 +30,6 @@ sudo certman new-domain example.com
|
||||
## Scratch Board
|
||||
- Server Flow
|
||||
- Read from
|
||||
|
||||
# Coding Conventions
|
||||
- Keep Config() calls in app space
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
15
server/acme_manager_test.go
Normal file
15
server/acme_manager_test.go
Normal 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")
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user