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.

certificate_manager.go 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package certs
  2. import (
  3. "go.uber.org/zap"
  4. "io/ioutil"
  5. "path"
  6. "strings"
  7. "time"
  8. )
  9. // CertificateManager handles scanning for new/updated certificates and deploying them to a destination.
  10. type CertificateManager struct {
  11. logger *zap.SugaredLogger
  12. directories []string
  13. }
  14. type foundCertificate struct {
  15. cert string
  16. chain string
  17. fullChain string
  18. privateKey string
  19. modTime time.Time
  20. }
  21. // NewCertificateManager creates a new CertificateManager.
  22. func NewCertificateManager(logger *zap.SugaredLogger) *CertificateManager {
  23. return &CertificateManager{
  24. logger: logger,
  25. }
  26. }
  27. func (c *CertificateManager) AddDirectory(directory string) {
  28. c.directories = append(c.directories, directory)
  29. go c.scanForFolders(directory)
  30. }
  31. func (c *CertificateManager) scanForFolders(dir string) {
  32. dirs, err := ioutil.ReadDir(dir)
  33. if err != nil {
  34. c.logger.Errorf("Unable to read directory %s - %s", dir, err.Error())
  35. return
  36. }
  37. for _, d := range dirs {
  38. if d.IsDir() {
  39. c.scanForCerts(d.Name(), path.Join(dir, d.Name()))
  40. }
  41. }
  42. }
  43. func (c *CertificateManager) scanForCerts(vhost string, dir string) {
  44. files, err := ioutil.ReadDir(dir)
  45. if err != nil {
  46. c.logger.Errorf("Unable to read directory %s - %s", dir, err.Error())
  47. return
  48. }
  49. cert := foundCertificate{}
  50. for _, f := range files {
  51. ext := path.Ext(f.Name())
  52. base := path.Base(f.Name())
  53. if ext == "" && strings.Contains(base, "-") {
  54. switch parts := strings.Split(base, "-"); parts[0] {
  55. case "cert":
  56. cert.cert = path.Join(dir, f.Name())
  57. if f.ModTime().After(cert.modTime) {
  58. cert.modTime = f.ModTime()
  59. }
  60. case "chain":
  61. cert.chain = path.Join(dir, f.Name())
  62. if f.ModTime().After(cert.modTime) {
  63. cert.modTime = f.ModTime()
  64. }
  65. case "fullchain":
  66. cert.fullChain = path.Join(dir, f.Name())
  67. if f.ModTime().After(cert.modTime) {
  68. cert.modTime = f.ModTime()
  69. }
  70. case "privkey":
  71. cert.privateKey = path.Join(dir, f.Name())
  72. if f.ModTime().After(cert.modTime) {
  73. cert.modTime = f.ModTime()
  74. }
  75. }
  76. }
  77. }
  78. if len(cert.cert) > 0 && len(cert.chain) > 0 && len(cert.fullChain) > 0 && len(cert.privateKey) > 0 {
  79. c.logger.Debugf("Found certificate files for %s in %s", vhost, dir)
  80. }
  81. }