diff options
| author | mo khan <mo@mokhan.ca> | 2025-03-31 14:14:07 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-03-31 14:14:07 -0600 |
| commit | f00c6bd0f622200cdc4da0455ed1d903ff67d99e (patch) | |
| tree | 3c7cef9c3e062a472ce1013138249ebf43029906 /magefiles/step.go | |
| parent | 3c3be9604e8c671ffca2f7a2bf4f34617545d8aa (diff) | |
chore: run local certificate authority
Diffstat (limited to 'magefiles/step.go')
| -rw-r--r-- | magefiles/step.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/magefiles/step.go b/magefiles/step.go new file mode 100644 index 00000000..02708020 --- /dev/null +++ b/magefiles/step.go @@ -0,0 +1,140 @@ +//go:build mage +// +build mage + +package main + +import ( + "context" + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + "github.com/magefile/mage/target" + "github.com/xlgmokha/x/pkg/env" + "github.com/xlgmokha/x/pkg/x" +) + +type Step mg.Namespace + +func (s Step) Clean() error { + globs := []string{ + "tmp/step/*/*", + } + for _, item := range globs { + fs, err := filepath.Glob(item) + if err != nil { + return err + } + for _, f := range fs { + if strings.HasSuffix(f, "/.keep") { + continue + } + if err := os.RemoveAll(f); err != nil { + return err + } + } + } + return nil +} + +func (s Step) Setup() { + mg.SerialDeps(s.mkPassword, s.createCA, s.enableACMEProvisioner) +} + +func (s Step) Install() error { + return sh.Run( + "step", + "certificate", + "install", + s.pathPlus("/certs/root_ca.crt"), + ) +} + +func (s Step) Server(ctx context.Context) error { + mg.SerialDeps(s.Setup) + + env := map[string]string{ + "STEPPATH": s.path(), + } + return sh.RunWithV( + env, + "step-ca", + s.pathPlus("config/ca.json"), + "--password-file="+s.pathPlus("password.txt"), + ) +} + +func (s Step) Provisioners() error { + return sh.RunV("curl", "-k", "-s", "https://localhost:8081/provisioners") +} + +func (s Step) ACME() error { + return sh.RunV("curl", "-k", "-s", "https://localhost:8081/acme/acme/directory") +} + +func (s Step) Status() { + mg.SerialDeps(s.Provisioners, s.ACME) +} + +func (s Step) mkPassword() error { + file := s.passwordFile() + if ok, err := target.Dir(file); err != nil || !ok { + return nil + } + + return os.WriteFile(file, []byte("password"), 0600) +} + +func (s Step) createCA() error { + if ok, err := target.Dir(s.pathPlus("config/ca.json"), s.passwordFile()); err != nil || !ok { + return nil + } + + return sh.Run( + "step", + "ca", + "init", + "--deployment-type=standalone", + "--address=localhost:8081", + "--dns=localhost", + "--dns=*.localhost", + "--name=CA", + "--provisioner=example", + "--provisioner-password-file="+s.passwordFile(), + "--password-file="+s.passwordFile(), + ) +} + +func (s Step) enableACMEProvisioner() error { + bytes, err := ioutil.ReadFile(s.pathPlus("config/ca.json")) + if err != nil { + return err + } + + items := map[string]interface{}{} + if err := json.Unmarshal(bytes, &items); err != nil { + return err + } + + provisioners := items["authority"].(map[string]interface{})["provisioners"].([]interface{}) + if len(provisioners) < 2 { + return sh.Run("step", "ca", "provisioner", "add", "acme", "--type", "ACME") + } + return nil +} + +func (step Step) passwordFile() string { + return step.pathPlus("password.txt") +} + +func (s Step) path() string { + return env.Fetch("STEPPATH", filepath.Join(x.Must(os.Getwd()), "/tmp/step")) +} + +func (s Step) pathPlus(path string) string { + return filepath.Join(s.path(), path) +} |
