Docker template generator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dotege.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/csmith/dotege/certs"
  5. "github.com/csmith/dotege/docker"
  6. "github.com/csmith/dotege/model"
  7. "github.com/docker/docker/client"
  8. "go.uber.org/zap"
  9. "go.uber.org/zap/zapcore"
  10. "os"
  11. "os/signal"
  12. "strings"
  13. "syscall"
  14. "time"
  15. )
  16. func monitorSignals() <-chan bool {
  17. signals := make(chan os.Signal, 1)
  18. done := make(chan bool, 1)
  19. signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
  20. go func() {
  21. sig := <-signals
  22. fmt.Printf("Received %s signal\n", sig)
  23. done <- true
  24. }()
  25. return done
  26. }
  27. func main() {
  28. zapConfig := zap.NewDevelopmentConfig()
  29. zapConfig.DisableCaller = true
  30. zapConfig.DisableStacktrace = true
  31. zapConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
  32. zapConfig.OutputPaths = []string{"stdout"}
  33. zapConfig.ErrorOutputPaths = []string{"stdout"}
  34. logger, _ := zapConfig.Build()
  35. sugar := logger.Sugar()
  36. sugar.Info("Dotege is starting")
  37. doneChan := monitorSignals()
  38. containerChan := make(chan model.Container, 1)
  39. expiryChan := make(chan string, 1)
  40. certChan := make(chan model.FoundCertificate, 1)
  41. config := model.Config{
  42. Labels: model.LabelConfig{
  43. Hostnames: "com.chameth.vhost",
  44. },
  45. DefaultCertActions: model.COMBINE | model.FLATTEN,
  46. DefaultCertDestination: "/data/certs/",
  47. }
  48. cli, err := client.NewEnvClient()
  49. if err != nil {
  50. panic(err)
  51. }
  52. certMonitor := certs.NewCertificateManager(sugar, certChan)
  53. certMonitor.AddDirectory("/data/certrequests/certs")
  54. templateGenerator := NewTemplateGenerator(sugar)
  55. templateGenerator.AddTemplate(model.TemplateConfig{
  56. Source: "./templates/domains.txt.tpl",
  57. Destination: "/data/certrequests/domains.txt",
  58. })
  59. templateGenerator.AddTemplate(model.TemplateConfig{
  60. Source: "./templates/haproxy.cfg.tpl",
  61. Destination: "haproxy.cfg",
  62. })
  63. monitor := docker.NewContainerMonitor(sugar, cli, containerChan, expiryChan)
  64. go monitor.Monitor()
  65. go func() {
  66. containers := make(map[string]model.Container)
  67. timer := time.NewTimer(time.Hour)
  68. timer.Stop()
  69. for {
  70. select {
  71. case container := <-containerChan:
  72. containers[container.Name] = container
  73. timer.Reset(100 * time.Millisecond)
  74. case name := <-expiryChan:
  75. delete(containers, name)
  76. timer.Reset(100 * time.Millisecond)
  77. case <-timer.C:
  78. templateGenerator.Generate(Context{
  79. Containers: containers,
  80. Hostnames: getHostnames(containers, config),
  81. })
  82. }
  83. }
  84. }()
  85. <-doneChan
  86. err = cli.Close()
  87. if err != nil {
  88. panic(err)
  89. }
  90. }
  91. func getHostnames(containers map[string]model.Container, config model.Config) (hostnames map[string]*model.Hostname) {
  92. hostnames = make(map[string]*model.Hostname)
  93. for _, container := range containers {
  94. if label, ok := container.Labels[config.Labels.Hostnames]; ok {
  95. names := strings.Split(strings.Replace(label, ",", " ", -1), " ")
  96. if hostname, ok := hostnames[names[0]]; ok {
  97. hostname.Containers = append(hostname.Containers, container)
  98. } else {
  99. hostnames[names[0]] = &model.Hostname{
  100. Name: names[0],
  101. Alternatives: make(map[string]bool),
  102. Containers: []model.Container{container},
  103. CertActions: config.DefaultCertActions,
  104. CertDestination: config.DefaultCertDestination,
  105. }
  106. }
  107. addAlternatives(hostnames[names[0]], names[1:])
  108. }
  109. }
  110. return
  111. }
  112. func addAlternatives(hostname *model.Hostname, alternatives []string) {
  113. for _, alternative := range alternatives {
  114. hostname.Alternatives[alternative] = true
  115. }
  116. }