Skip to content

Commit 40663ff

Browse files
Load database password from a file (#307)
* Password file Signed-off-by: Anders Swanson <[email protected]> * Web config file Signed-off-by: Anders Swanson <[email protected]> * Password file Signed-off-by: Anders Swanson <[email protected]> --------- Signed-off-by: Anders Swanson <[email protected]>
1 parent 47398c4 commit 40663ff

File tree

5 files changed

+65
-15
lines changed

5 files changed

+65
-15
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,9 @@ databases:
692692
username: ${DB_USERNAME}
693693
## Database password
694694
password: ${DB_PASSWORD}
695+
## Database password file
696+
## If specified, will load the database password from a file.
697+
# passwordFile: ${DB_PASSWORD_FILE}
695698
## Database connection url
696699
url: localhost:1521/freepdb1
697700
@@ -729,6 +732,11 @@ databases:
729732
# label_name1: label_value1
730733
# label_name2: label_value2
731734
735+
# Optionally configure prometheus webserver
736+
#web:
737+
# listenAddresses: [':9161']
738+
# systemdSocket: true|false
739+
# configFile: /path/to/webconfigfile
732740
733741
metrics:
734742
## How often to scrape metrics. If not provided, metrics will be scraped on request.

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
Our current priorities are support for Exadata metrics. We expect to address these in an upcoming release.
66

77
This release includes the following changes:
8+
- Enable configuration of the prometheus webserver from the config file using the `web` prefix.
9+
- Allow loading of database password(s) from a file.
810
- Fixed a bug where database type (CDB, PDB, etc.) was not reported in certain situations.
911
- Fixed a bug where literal passwords containing the '$' character (in the config file) would be evaluated as environment variables. To use literal passwords with the '$' character, escape the '$' character with a second '$': `$test$pwd` becomes `$$test$$pwd`.
1012

collector/config.go

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
package collector
55

66
import (
7+
"fmt"
78
"github.com/godror/godror/dsn"
89
"github.com/oracle/oracle-db-appdev-monitoring/azvault"
910
"github.com/oracle/oracle-db-appdev-monitoring/ocivault"
11+
"github.com/prometheus/exporter-toolkit/web"
1012
"gopkg.in/yaml.v2"
1113
"log/slog"
1214
"os"
@@ -15,15 +17,24 @@ import (
1517
)
1618

1719
type MetricsConfiguration struct {
18-
MetricsPath string `yaml:"metricsPath"`
19-
Databases map[string]DatabaseConfig `yaml:"databases"`
20-
Metrics MetricsFilesConfig `yaml:"metrics"`
21-
Logging LoggingConfig `yaml:"log"`
20+
ListenAddress string `yaml:"listenAddress"`
21+
MetricsPath string `yaml:"metricsPath"`
22+
Databases map[string]DatabaseConfig `yaml:"databases"`
23+
Metrics MetricsFilesConfig `yaml:"metrics"`
24+
Logging LoggingConfig `yaml:"log"`
25+
Web WebConfig `yaml:"web"`
26+
}
27+
28+
type WebConfig struct {
29+
ListenAddresses *[]string `yaml:"listenAddresses"`
30+
SystemdSocket *bool `yaml:"systemdSocket"`
31+
ConfigFile *string `yaml:"configFile"`
2232
}
2333

2434
type DatabaseConfig struct {
2535
Username string
2636
Password string
37+
PasswordFile string `yaml:"passwordFile"`
2738
URL string `yaml:"url"`
2839
ConnectConfig `yaml:",inline"`
2940
Vault *VaultConfig `yaml:"vault,omitempty"`
@@ -146,6 +157,14 @@ func (d DatabaseConfig) GetUsername() string {
146157
}
147158

148159
func (d DatabaseConfig) GetPassword() string {
160+
if d.PasswordFile != "" {
161+
bytes, err := os.ReadFile(d.PasswordFile)
162+
if err != nil {
163+
// If there is an invalid file, exporter cannot continue processing.
164+
panic(fmt.Errorf("failed to read password file: %v", err))
165+
}
166+
return string(bytes)
167+
}
149168
if d.isOCIVault() && d.Vault.OCI.PasswordSecret != "" {
150169
return ocivault.GetVaultSecret(d.Vault.OCI.ID, d.Vault.OCI.PasswordSecret)
151170
}
@@ -163,7 +182,7 @@ func (d DatabaseConfig) isAzureVault() bool {
163182
return d.Vault != nil && d.Vault.Azure != nil
164183
}
165184

166-
func LoadMetricsConfiguration(logger *slog.Logger, cfg *Config, path string) (*MetricsConfiguration, error) {
185+
func LoadMetricsConfiguration(logger *slog.Logger, cfg *Config, path string, flags *web.FlagConfig) (*MetricsConfiguration, error) {
167186
m := &MetricsConfiguration{}
168187
if len(cfg.ConfigFile) > 0 {
169188
content, err := os.ReadFile(cfg.ConfigFile)
@@ -186,21 +205,42 @@ func LoadMetricsConfiguration(logger *slog.Logger, cfg *Config, path string) (*M
186205
m.Databases["default"] = m.defaultDatabase(cfg)
187206
}
188207

189-
m.merge(cfg, path)
208+
m.merge(cfg, path, flags)
190209
return m, nil
191210
}
192211

193-
func (m *MetricsConfiguration) merge(cfg *Config, path string) {
212+
func (wc WebConfig) Flags() *web.FlagConfig {
213+
return &web.FlagConfig{
214+
WebListenAddresses: wc.ListenAddresses,
215+
WebSystemdSocket: wc.SystemdSocket,
216+
WebConfigFile: wc.ConfigFile,
217+
}
218+
}
219+
220+
func (m *MetricsConfiguration) merge(cfg *Config, path string, flags *web.FlagConfig) {
194221
if len(m.MetricsPath) == 0 {
195222
m.MetricsPath = path
196223
}
224+
m.mergeWebConfig(flags)
197225
m.mergeLoggingConfig(cfg)
198226
m.mergeMetricsConfig(cfg)
199227
if m.Metrics.ScrapeInterval == nil {
200228
m.Metrics.ScrapeInterval = &cfg.ScrapeInterval
201229
}
202230
}
203231

232+
func (m *MetricsConfiguration) mergeWebConfig(flags *web.FlagConfig) {
233+
if m.Web.ListenAddresses == nil {
234+
m.Web.ListenAddresses = flags.WebListenAddresses
235+
}
236+
if m.Web.SystemdSocket == nil {
237+
m.Web.SystemdSocket = flags.WebSystemdSocket
238+
}
239+
if m.Web.ConfigFile == nil {
240+
m.Web.ConfigFile = flags.WebConfigFile
241+
}
242+
}
243+
204244
func (m *MetricsConfiguration) mergeLoggingConfig(cfg *Config) {
205245
if m.Logging.LogDisable == nil {
206246
m.Logging.LogDisable = cfg.LoggingConfig.LogDisable

collector/database.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ func (d *Database) constLabels(labels map[string]string) map[string]string {
7878
func NewDatabase(logger *slog.Logger, dbname string, dbconfig DatabaseConfig) *Database {
7979
db, dbtype := connect(logger, dbname, dbconfig)
8080
return &Database{
81-
Name: dbname,
82-
Up: 0,
83-
Session: db,
84-
Type: dbtype,
85-
Config: dbconfig,
81+
Name: dbname,
82+
Up: 0,
83+
Session: db,
84+
Type: dbtype,
85+
Config: dbconfig,
8686
}
8787
}
8888

main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ func main() {
105105
LogDestination: *logDestination,
106106
},
107107
}
108-
m, err := collector.LoadMetricsConfiguration(logger, config, *metricPath)
108+
m, err := collector.LoadMetricsConfiguration(logger, config, *metricPath, toolkitFlags)
109109
if err != nil {
110110
logger.Error("unable to load metrics configuration", "error", err)
111111
return
112112
}
113-
113+
114114
exporter := collector.NewExporter(logger, m)
115115
if exporter.ScrapeInterval() != 0 {
116116
ctx, cancel := context.WithCancel(context.Background())
@@ -194,7 +194,7 @@ func main() {
194194

195195
// start the main server thread
196196
server := &http.Server{}
197-
if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil {
197+
if err := web.ListenAndServe(server, m.Web.Flags(), logger); err != nil {
198198
logger.Error("Listening error", "error", err)
199199
os.Exit(1)
200200
}

0 commit comments

Comments
 (0)