Skip to content

Commit

Permalink
Merge pull request #114 from qonto/support-ssl
Browse files Browse the repository at this point in the history
Add support of TLS
  • Loading branch information
vmercierfr authored Jan 25, 2024
2 parents d3f979b + f82aa5d commit 89cf6a5
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ Configuration could be defined in [prometheus-rds-exporter.yaml](https://github.
| listen-address | Address to listen on for web interface | :9043 |
| log-format | Log format (`text` or `json`) | json |
| metrics-path | Path under which to expose metrics | /metrics |
| tls-cert-path | Path to TLS certificate | |
| tls-key-path | Path to private key for TLS |

Configuration parameters priorities:

Expand Down
23 changes: 22 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var cfgFile string
type exporterConfig struct {
Debug bool `mapstructure:"debug"`
LogFormat string `mapstructure:"log-format"`
TLSCertPath string `mapstructure:"tls-cert-path"`
TLSKeyPath string `mapstructure:"tls-key-path"`
MetricPath string `mapstructure:"metrics-path"`
ListenAddress string `mapstructure:"listen-address"`
AWSAssumeRoleSession string `mapstructure:"aws-assume-role-session"`
Expand Down Expand Up @@ -83,7 +85,14 @@ func run(configuration exporterConfig) {

prometheus.MustRegister(collector)

server := http.New(*logger, configuration.ListenAddress, configuration.MetricPath)
serverConfiguration := http.Config{
ListenAddress: configuration.ListenAddress,
MetricPath: configuration.MetricPath,
TLSCertPath: configuration.TLSCertPath,
TLSKeyPath: configuration.TLSKeyPath,
}

server := http.New(*logger, serverConfiguration)

err = server.Start()
if err != nil {
Expand Down Expand Up @@ -117,6 +126,8 @@ func NewRootCommand() (*cobra.Command, error) {
cmd.Flags().BoolP("debug", "d", false, "Enable debug mode")
cmd.Flags().StringP("log-format", "l", "json", "Log format (text or json)")
cmd.Flags().StringP("metrics-path", "", "/metrics", "Path under which to expose metrics")
cmd.Flags().StringP("tls-cert-path", "", "", "Path to TLS certificate")
cmd.Flags().StringP("tls-key-path", "", "", "Path to private key for TLS")
cmd.Flags().StringP("listen-address", "", ":9043", "Address to listen on for web interface")
cmd.Flags().StringP("aws-assume-role-arn", "", "", "AWS IAM ARN role to assume to fetch metrics")
cmd.Flags().StringP("aws-assume-role-session", "", "prometheus-rds-exporter", "AWS assume role session name")
Expand All @@ -143,6 +154,16 @@ func NewRootCommand() (*cobra.Command, error) {
return cmd, fmt.Errorf("failed to bind 'metrics-path' parameter: %w", err)
}

err = viper.BindPFlag("tls-cert-path", cmd.Flags().Lookup("tls-cert-path"))
if err != nil {
return cmd, fmt.Errorf("failed to bind 'tls-cert-path' parameter: %w", err)
}

err = viper.BindPFlag("tls-key-path", cmd.Flags().Lookup("tls-key-path"))
if err != nil {
return cmd, fmt.Errorf("failed to bind 'tls-key-path' parameter: %w", err)
}

err = viper.BindPFlag("listen-address", cmd.Flags().Lookup("listen-address"))
if err != nil {
return cmd, fmt.Errorf("failed to bind 'listen-address' parameter: %w", err)
Expand Down
10 changes: 8 additions & 2 deletions configs/prometheus-rds-exporter/prometheus-rds-exporter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
# Enable debug mode
# debug: false

# Log format (text or json)
# log-format: json

# Path under which to expose metrics
# metrics-path: /metrics

# Address to listen on for web interface
# listen-address: ":9043"

# Log format (text or json)
# log-format: json
# Path to TLS certificate
# tls-cert-path: ""

# Path to private key for TLS
# tls-key-path: ""

#
# AWS credentials
Expand Down
19 changes: 19 additions & 0 deletions docs/add-configuration-parameter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Add a configuration parameter

This document explains how to add a configuration parameter in the exporter.

Steps:

1. Define parameter name

1. Implement it

1. Add a new field in `exporterConfig` structure in `cmd/root.go`
1. Add the parameter in flag `cmd.Flags()`
1. Add the parameter in viper `viper.BindPFlag()`

1. Add tests

1. Add parameter in the `README.md`

1. Add parameter in YAML default configuration file in `configs/prometheus-rds-exporter/prometheus-rds-exporter.yaml`
40 changes: 23 additions & 17 deletions internal/infra/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,47 @@ const (
)

type Component struct {
config config
config *Config
logger *slog.Logger
server *http.Server
}

type config struct {
metricPath string
listenAddress string
type Config struct {
MetricPath string
ListenAddress string
TLSKeyPath string
TLSCertPath string
}

func New(logger slog.Logger, listenAddress string, metricPath string) (component Component) {
func New(logger slog.Logger, config Config) (component Component) {
component = Component{
logger: &logger,
config: config{
metricPath: metricPath,
listenAddress: listenAddress,
},
config: &config,
}

return
}

func (c *Component) Start() error {
c.logger.Info("starting the HTTP server component")

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

c.server = &http.Server{
Addr: c.config.listenAddress,
Addr: c.config.ListenAddress,
ReadTimeout: ReadTimeout * time.Second,
WriteTimeout: WriteTimeout * time.Second,
IdleTimeout: IdleTimeout * time.Second,
ReadHeaderTimeout: ReadHeaderTimeout * time.Second,
BaseContext: func(_ net.Listener) context.Context { return ctx },
}

homepage, err := NewHomePage(build.Version, c.config.metricPath)
homepage, err := NewHomePage(build.Version, c.config.MetricPath)
if err != nil {
return fmt.Errorf("hompage initialization failed: %w", err)
}

http.Handle("/", homepage)
http.Handle(c.config.metricPath, promhttp.Handler())
http.Handle(c.config.MetricPath, promhttp.Handler())

signalChan := make(chan os.Signal, 1)
signal.Notify(
Expand All @@ -81,7 +78,16 @@ func (c *Component) Start() error {
)

go func() {
err := c.server.ListenAndServe()
var err error

if c.config.TLSCertPath != "" && c.config.TLSKeyPath != "" {
c.logger.Info("starting the HTTPS server component")
err = c.server.ListenAndServeTLS(c.config.TLSCertPath, c.config.TLSKeyPath)
} else {
c.logger.Info("starting the HTTP server component")
err = c.server.ListenAndServe()
}

if err != nil && !errors.Is(err, http.ErrServerClosed) {
c.logger.Error("can't start web server", "reason", err)
os.Exit(httpErrorExitCode)
Expand All @@ -99,7 +105,7 @@ func (c *Component) Start() error {
}

func (c *Component) Stop() error {
c.logger.Info("stopping the HTTP server component")
c.logger.Info("stopping the web server component")

ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout*time.Second)
defer cancel()
Expand All @@ -109,7 +115,7 @@ func (c *Component) Stop() error {
return fmt.Errorf("can't stop webserver: %w", err)
}

c.logger.Info("HTTP server stopped")
c.logger.Info("web server stopped")

return nil
}

0 comments on commit 89cf6a5

Please sign in to comment.