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.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. config := zap.NewDevelopmentConfig()
  29. config.DisableCaller = true
  30. config.DisableStacktrace = true
  31. config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
  32. config.OutputPaths = []string{"stdout"}
  33. config.ErrorOutputPaths = []string{"stdout"}
  34. logger, _ := config.Build()
  35. sugar := logger.Sugar()
  36. sugar.Info("Dotege is starting")
  37. done := monitorSignals()
  38. containerChan := make(chan model.Container, 1)
  39. expiryChan := make(chan string, 1)
  40. labelConfig := model.LabelConfig{
  41. Hostnames: "com.chameth.vhost",
  42. }
  43. cli, err := client.NewEnvClient()
  44. if err != nil {
  45. panic(err)
  46. }
  47. certMonitor := certs.NewCertificateManager(sugar)
  48. certMonitor.AddDirectory("/certs/certs")
  49. templateGenerator := NewTemplateGenerator(sugar)
  50. templateGenerator.AddTemplate(model.TemplateConfig{
  51. Source: "./templates/domains.txt.tpl",
  52. Destination: "domains.txt",
  53. })
  54. templateGenerator.AddTemplate(model.TemplateConfig{
  55. Source: "./templates/haproxy.cfg.tpl",
  56. Destination: "haproxy.cfg",
  57. })
  58. monitor := docker.NewContainerMonitor(sugar, cli, containerChan, expiryChan)
  59. go monitor.Monitor()
  60. go func() {
  61. containers := make(map[string]model.Container)
  62. timer := time.NewTimer(time.Hour)
  63. timer.Stop()
  64. for {
  65. select {
  66. case container := <-containerChan:
  67. containers[container.Name] = container
  68. timer.Reset(100 * time.Millisecond)
  69. case name := <-expiryChan:
  70. delete(containers, name)
  71. timer.Reset(100 * time.Millisecond)
  72. case <-timer.C:
  73. templateGenerator.Generate(Context{
  74. Containers: containers,
  75. Hostnames: getHostnames(containers, labelConfig),
  76. })
  77. }
  78. }
  79. }()
  80. <-done
  81. err = cli.Close()
  82. if err != nil {
  83. panic(err)
  84. }
  85. }
  86. func getHostnames(containers map[string]model.Container, config model.LabelConfig) (hostnames map[string]*model.Hostname) {
  87. hostnames = make(map[string]*model.Hostname)
  88. for _, container := range containers {
  89. if label, ok := container.Labels[config.Hostnames]; ok {
  90. names := strings.Split(strings.Replace(label, ",", " ", -1), " ")
  91. if hostname, ok := hostnames[names[0]]; ok {
  92. hostname.Containers = append(hostname.Containers, container)
  93. } else {
  94. hostnames[names[0]] = &model.Hostname{
  95. Name: names[0],
  96. Alternatives: make(map[string]bool),
  97. Containers: []model.Container{container},
  98. }
  99. }
  100. addAlternatives(hostnames[names[0]], names[1:])
  101. }
  102. }
  103. return
  104. }
  105. func addAlternatives(hostname *model.Hostname, alternatives []string) {
  106. for _, alternative := range alternatives {
  107. hostname.Alternatives[alternative] = true
  108. }
  109. }