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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. certDeployer := certs.NewCertificateDeployer(sugar, certChan)
  55. templateGenerator := NewTemplateGenerator(sugar)
  56. templateGenerator.AddTemplate(model.TemplateConfig{
  57. Source: "./templates/domains.txt.tpl",
  58. Destination: "/data/certrequests/domains.txt",
  59. })
  60. templateGenerator.AddTemplate(model.TemplateConfig{
  61. Source: "./templates/haproxy.cfg.tpl",
  62. Destination: "haproxy.cfg",
  63. })
  64. monitor := docker.NewContainerMonitor(sugar, cli, containerChan, expiryChan)
  65. go monitor.Monitor()
  66. go func() {
  67. containers := make(map[string]model.Container)
  68. timer := time.NewTimer(time.Hour)
  69. timer.Stop()
  70. for {
  71. select {
  72. case container := <-containerChan:
  73. containers[container.Name] = container
  74. timer.Reset(100 * time.Millisecond)
  75. case name := <-expiryChan:
  76. delete(containers, name)
  77. timer.Reset(100 * time.Millisecond)
  78. case <-timer.C:
  79. hostnames := getHostnames(containers, config)
  80. templateGenerator.Generate(Context{
  81. Containers: containers,
  82. Hostnames: hostnames,
  83. })
  84. certDeployer.UpdateHostnames(hostnames)
  85. }
  86. }
  87. }()
  88. <-doneChan
  89. err = cli.Close()
  90. if err != nil {
  91. panic(err)
  92. }
  93. }
  94. func getHostnames(containers map[string]model.Container, config model.Config) (hostnames map[string]*model.Hostname) {
  95. hostnames = make(map[string]*model.Hostname)
  96. for _, container := range containers {
  97. if label, ok := container.Labels[config.Labels.Hostnames]; ok {
  98. names := strings.Split(strings.Replace(label, ",", " ", -1), " ")
  99. if hostname, ok := hostnames[names[0]]; ok {
  100. hostname.Containers = append(hostname.Containers, container)
  101. } else {
  102. hostnames[names[0]] = &model.Hostname{
  103. Name: names[0],
  104. Alternatives: make(map[string]bool),
  105. Containers: []model.Container{container},
  106. CertActions: config.DefaultCertActions,
  107. CertDestination: config.DefaultCertDestination,
  108. }
  109. }
  110. addAlternatives(hostnames[names[0]], names[1:])
  111. }
  112. }
  113. return
  114. }
  115. func addAlternatives(hostname *model.Hostname, alternatives []string) {
  116. for _, alternative := range alternatives {
  117. hostname.Alternatives[alternative] = true
  118. }
  119. }