github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/tls/tls.go (about) 1 package tls 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring" 9 promconfig "github.com/prometheus/common/config" 10 "github.com/rs/zerolog" 11 ) 12 13 func SMtoProm(ctx context.Context, logger zerolog.Logger, tlsConfig *sm.TLSConfig) (promconfig.TLSConfig, error) { 14 c := promconfig.TLSConfig{ 15 InsecureSkipVerify: tlsConfig.InsecureSkipVerify, 16 ServerName: tlsConfig.ServerName, 17 } 18 19 if len(tlsConfig.CACert) > 0 { 20 fn, err := newDataProvider(ctx, logger, "ca_cert", tlsConfig.CACert) 21 if err != nil { 22 return promconfig.TLSConfig{}, err 23 } 24 25 c.CAFile = fn 26 } 27 28 if len(tlsConfig.ClientCert) > 0 { 29 fn, err := newDataProvider(ctx, logger, "client_cert", tlsConfig.ClientCert) 30 if err != nil { 31 return promconfig.TLSConfig{}, err 32 } 33 34 c.CertFile = fn 35 } 36 37 if len(tlsConfig.ClientKey) > 0 { 38 fn, err := newDataProvider(ctx, logger, "client_key", tlsConfig.ClientKey) 39 if err != nil { 40 return promconfig.TLSConfig{}, err 41 } 42 43 c.KeyFile = fn 44 } 45 46 return c, nil 47 } 48 49 // newDataProvider creates a filesystem object that provides the 50 // specified data as often as needed. It returns the name under which 51 // the data can be accessed. 52 // 53 // It does NOT try to make guarantees about partial reads. If the reader 54 // goes away before reaching the end of the data, the next time the 55 // reader shows up, the writer might continue from the previous 56 // prosition. 57 func newDataProvider(ctx context.Context, logger zerolog.Logger, basename string, data []byte) (string, error) { 58 fh, err := os.CreateTemp("", basename+".") 59 if err != nil { 60 logger.Error().Err(err).Str("basename", basename).Msg("creating temporary file") 61 return "", fmt.Errorf("creating temporary file: %w", err) 62 } 63 64 defer func() { 65 if err := fh.Close(); err != nil { 66 // close errors should never happen, but if they 67 // do, the most we can do is log them to be able 68 // to debug the issue. 69 logger.Error().Err(err).Str("filename", fh.Name()).Msg("closing temporary file") 70 } 71 }() 72 73 fn := fh.Name() 74 75 if n, err := fh.Write(data); err != nil { 76 logger.Error().Err(err).Str("filename", fn).Int("bytes", n).Int("data", len(data)).Msg("writing temporary file") 77 return "", fmt.Errorf("writing temporary file for %s: %w", basename, err) 78 } 79 80 // play nice and make sure this file gets deleted once the 81 // context is cancelled, which could be when the program is 82 // shutting down or when the scraper stops. 83 go func() { 84 <-ctx.Done() 85 86 if err := os.Remove(fn); err != nil { 87 logger.Error().Err(err).Str("filename", fn).Msg("removing temporary file") 88 } 89 }() 90 91 return fn, nil 92 }