Skip to content

Commit

Permalink
add service mode
Browse files Browse the repository at this point in the history
  • Loading branch information
nett00n committed Aug 25, 2023
1 parent a8862e6 commit ac8d0f9
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 14 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
*.cer
*.json
*.key
!.gitignore
!.github

certs
output
traefik-certs-exporter

!.github
!.gitignore
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Traefik certs exporter

[![Run revive linters](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linter_revive.yml/badge.svg?branch=main)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linter_revive.yml)
[![Build linux binaries](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linux_build.yml/badge.svg?branch=main)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linux_build.yml)
[![Push to Dockerhub](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/docker_push.yml/badge.svg)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/docker_push.yml)
[![Run revive linters](https://github.com/5mdt/traefik-certs-exporter/actions/workflows/linter_revive.yml/badge.svg?branch=main)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linter_revive.yml)
[![Build linux binaries](https://github.com/5mdt/traefik-certs-exporter/actions/workflows/linux_build.yml/badge.svg?branch=main)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/linux_build.yml)
[![Push to Dockerhub](https://github.com/5mdt/traefik-certs-exporter/actions/workflows/docker_push.yml/badge.svg)](https://github.com/nett00n/traefik-certs-exporter/actions/workflows/docker_push.yml)

Script opens `acme.json` file used by traefik and export it's content to `output` folder as `*.cer` and `*.key` files.

Expand All @@ -13,10 +13,16 @@ There is template `acme.json` file in `input` directory for demonstration purpos
Run app

```bash
go run traefik-certs-exporter.go -acmejson=/foo/acme.json -output=/bar/certs/
go run traefik-certs-exporter.go --acmejson=/foo/acme.json --output=/bar/certs/
```
### Flags

- `acmejson` - path to source file
- `output` - path to directory for savind files
- `service` - if you run app like a service
-
#### Defaults

### defaults
- `acmejson`=`./input/acme.json`
- `output`=`./output`

Expand All @@ -28,8 +34,8 @@ docker run -v ${PWD}/input:/input -v ${PWD}/output:/output: docker.io/nett00n/tr

## Links

- [Gihtub Project](https://github.com/nett00n/traefik-certs-exporter)
- [DockerHub Page](https://hub.docker.com/r/nett00n/traefik-certs-exporter)
- [Gihtub Project](https://github.com/5mdt/traefik-certs-exporter)
- [DockerHub Page](https://hub.docker.com/r/5mdt/traefik-certs-exporter)

## License

Expand All @@ -40,4 +46,4 @@ All code in this repository is licensed under the terms of the MIT License. For
- Vladimir Budylnikov aka [@nett00n](https://github.com/nett00n)

---
2023, Yerevan
2022-2023, Yerevan, Tbilisi
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module traefik-certs-exporter

go 1.19

require github.com/fsnotify/fsnotify v1.6.0

require golang.org/x/sys v0.11.0 // indirect
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
53 changes: 49 additions & 4 deletions traefik-certs-exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"encoding/base64"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"time"

"github.com/fsnotify/fsnotify"
)

// ACME is an imported global traefik acme.json structure
Expand Down Expand Up @@ -41,10 +43,22 @@ func main() {
// Parse command-line arguments
acmeJSONPath := flag.String("acmejson", "input/acme.json", "Path to the acme.json file")
outputDir := flag.String("output", "output", "Path to the output directory")
serviceMode := flag.Bool("service", false, "Enable service mode to monitor acme.json for changes")

flag.Parse()

if *serviceMode {
// Run in service mode
runServiceMode(*acmeJSONPath, *outputDir)
} else {
// Run once
exportCertificates(*acmeJSONPath, *outputDir)
}
}

func exportCertificates(acmeJSONPath, outputDir string) {
// Open acme.json file
jsonFile, err := os.Open(*acmeJSONPath)
jsonFile, err := os.Open(acmeJSONPath)
if err != nil {
log.Fatal(err)
}
Expand All @@ -64,12 +78,12 @@ func main() {
}

// Create output directory if not exists
if err := os.MkdirAll(*outputDir, os.ModePerm); err != nil {
if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
log.Fatal(err)
}

for _, cert := range traefik.Le.Certificates {
domainDir := filepath.Join(*outputDir, cert.Domain.Main)
domainDir := filepath.Join(outputDir, cert.Domain.Main)
if err := os.MkdirAll(domainDir, os.ModePerm); err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -101,3 +115,34 @@ func main() {
log.Println("Saved certificate and key for", cert.Domain.Main)
}
}

func runServiceMode(acmeJSONPath, outputDir string) {
exportCertificates(acmeJSONPath, outputDir)

watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()

err = watcher.Add(acmeJSONPath)
if err != nil {
log.Fatal(err)
}

log.Printf("Monitoring %s for changes...\n", acmeJSONPath)

for {
select {
case event := <-watcher.Events:
if event.Op&fsnotify.Write == fsnotify.Write {
log.Println("acme.json has been modified. Exporting certificates...")
exportCertificates(acmeJSONPath, outputDir)
}
case err := <-watcher.Errors:
log.Println("Error:", err)
}
// Sleep for a moment to avoid high CPU usage in the loop
time.Sleep(1000 * time.Millisecond)
}
}

0 comments on commit ac8d0f9

Please sign in to comment.