Skip to content

Commit 69ee1c9

Browse files
authored
Merge pull request #162 from Icinga/config-from-env
Load config from both env and yaml
2 parents 6a4db6c + c2153da commit 69ee1c9

File tree

7 files changed

+148
-46
lines changed

7 files changed

+148
-46
lines changed

cmd/icinga-kubernetes/main.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,20 @@ const expectedSchemaVersion = "0.2.0"
4949
func main() {
5050
runtime.ReallyCrash = true
5151

52-
var configLocation string
52+
var glue daemon.ConfigFlagGlue
5353
var showVersion bool
5454
var clusterName string
5555

5656
klog.InitFlags(nil)
5757
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
5858

5959
pflag.BoolVar(&showVersion, "version", false, "print version and exit")
60-
pflag.StringVar(&configLocation, "config", "./config.yml", "path to the config file")
60+
pflag.StringVar(
61+
&glue.Config,
62+
"config",
63+
"",
64+
fmt.Sprintf("path to the config file (default: %s)", daemon.DefaultConfigPath),
65+
)
6166
pflag.StringVar(&clusterName, "cluster-name", "", "name of the current cluster")
6267

6368
loadingRules := kclientcmd.NewDefaultClientConfigLoadingRules()
@@ -98,9 +103,12 @@ func main() {
98103
log := klog.NewKlogr()
99104

100105
var cfg daemon.Config
101-
err = config.FromYAMLFile(configLocation, &cfg)
102-
if err != nil {
103-
klog.Fatal(errors.Wrap(err, "cannot create configuration"))
106+
107+
if err = config.Load(&cfg, config.LoadOptions{
108+
Flags: glue,
109+
EnvOptions: config.EnvOptions{Prefix: "ICINGA_FOR_KUBERNETES_"},
110+
}); err != nil {
111+
klog.Fatal(errors.Wrap(err, "can't create configuration"))
104112
}
105113

106114
dbLog := log.WithName("database")

doc/03-Configuration.md

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Configuration
1+
# Configuration via YAML File
22

33
The configuration is stored in `/etc/icinga-kubernetes/config.yml`.
44
See [config.example.yml](../config.example.yml) for an example configuration.
@@ -9,27 +9,93 @@ Connection configuration for the database to which Icinga for Kubernetes synchro
99
This is also the database used in
1010
[Icinga for Kubernetes Web](https://icinga.com/docs/icinga-kubernetes-web) to view and work with the data.
1111

12-
| Option | Description |
13-
|----------|--------------------------------------------------------------------|
14-
| type | **Optional.** Only `mysql` is supported yet which is the default. |
15-
| host | **Required.** Database host or absolute Unix socket path. |
16-
| port | **Optional.** Database port. By default, the MySQL port. |
17-
| database | **Required.** Database name. |
18-
| user | **Required.** Database username. |
19-
| password | **Optional.** Database password. |
20-
| tls | **Optional.** Whether to use TLS. |
21-
| cert | **Optional.** Path to TLS client certificate. |
22-
| key | **Optional.** Path to TLS private key. |
23-
| ca | **Optional.** Path to TLS CA certificate. |
24-
| insecure | **Optional.** Whether not to verify the peer. |
12+
| Option | Description |
13+
|----------|-------------------------------------------------------------------|
14+
| type | **Optional.** Only `mysql` is supported yet which is the default. |
15+
| host | **Required.** Database host or absolute Unix socket path. |
16+
| port | **Optional.** Database port. By default, the MySQL port. |
17+
| database | **Required.** Database name. |
18+
| user | **Required.** Database username. |
19+
| password | **Optional.** Database password. |
20+
| tls | **Optional.** Whether to use TLS. |
21+
| cert | **Optional.** Path to TLS client certificate. |
22+
| key | **Optional.** Path to TLS private key. |
23+
| ca | **Optional.** Path to TLS CA certificate. |
24+
| insecure | **Optional.** Whether not to verify the peer. |
25+
26+
## Logging Configuration
27+
28+
| Env | Description |
29+
|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
30+
| level | **Optional.** Default logging level. Can be set to `fatal`, `error`, `warn`, `info` or `debug`. If not set, defaults to `info`. |
31+
| output | **Optional.** Logging output. Can be set to `console` (stderr) or `systemd-journald`. If not set, logs to systemd-journald when running under systemd, otherwise stderr. |
32+
| interval | **Optional.** Interval for periodic logging defined as duration string. Valid units are `ms`, `s`, `m`, `h`. Defaults to `20s`. |
33+
34+
## Notifications Configuration
35+
36+
Connection configuration for [Icinga Notifications](https://github.com/icinga/icinga-notifications) daemon.
37+
If one of `url`, `username`, or `password` is set, **all** must be set.
38+
Defined in the `notifications` section of the configuration file.
39+
40+
| Option | Description |
41+
|--------------------|-------------------------------------------------------------------------------------------------------|
42+
| url | **Optional.** Icinga Notifications daemon URL. If not set, notifications are disabled |
43+
| username | **Optional.** Username for authenticating the Icinga for Kubernetes source in Icinga Notifications. |
44+
| password | **Optional.** Password for authenticating the Icinga for Kubernetes source in Icinga Notifications. |
45+
| kubernetes_web_url | **Optional.** The base URL of Icinga for Kubernetes Web used in generated Icinga Notification events. |
2546

2647
## Prometheus Configuration
2748

2849
Connection configuration for a Prometheus instance that collects metrics from your Kubernetes cluster,
2950
from which Icinga for Kubernetes [synchronizes predefined metrics](01-About.md#metric-sync) to display charts in the UI.
30-
Defined in the `prometheus` section of the configuration file.
51+
Defined in the `prometheus` section of the configuration file. If one of username or password is set, both must be set.
3152

3253
| Option | Description |
3354
|----------|----------------------------------------------------------------------------------------------------------------------------|
3455
| url | **Optional.** Prometheus server URL. If not set, metric synchronization is disabled. |
3556
| insecure | **Optional.** Skip the TLS/SSL certificate verification. Can be set to 'true' or 'false'. If not set, defaults to 'false'. |
57+
| username | **Optional.** Prometheus username. |
58+
| password | **Optional.** Prometheus password. |
59+
60+
# Configuration via Environment Variables
61+
62+
**All** environment variables are prefixed with `ICINGA_FOR_KUBERNETES_`.
63+
The database type would therefore be `ICINGA_FOR_KUBERNETES_DATABASE_TYPE`.
64+
The configurations set by environment variables override the ones set by YAML.
65+
66+
## Database Configuration
67+
68+
| Env | Description |
69+
|-------------------|-------------------------------------------------------------------|
70+
| DATABASE_TYPE | **Optional.** Only `mysql` is supported yet which is the default. |
71+
| DATABASE_HOST | **Required.** Database host or absolute Unix socket path. |
72+
| DATABASE_PORT | **Optional.** Database port. By default, the MySQL port. |
73+
| DATABASE_DATABASE | **Required.** Database name. |
74+
| DATABASE_USER | **Required.** Database username. |
75+
| DATABASE_PASSWORD | **Optional.** Database password. |
76+
77+
## Logging Configuration
78+
79+
| Env | Description |
80+
|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
81+
| LOGGING_LEVEL | **Optional.** Default logging level. Can be set to `fatal`, `error`, `warn`, `info` or `debug`. If not set, defaults to `info`. |
82+
| LOGGING_OUTPUT | **Optional.** Logging output. Can be set to `console` (stderr) or `systemd-journald`. If not set, logs to systemd-journald when running under systemd, otherwise stderr. |
83+
| LOGGING_INTERVAL | **Optional.** Interval for periodic logging defined as duration string. Valid units are `ms`, `s`, `m`, `h`. Defaults to `20s`. |
84+
85+
## Notifications Configuration
86+
87+
| Env | Description |
88+
|----------------------------------|-------------------------------------------------------------------------------------------------------|
89+
| NOTIFICATIONS_URL | **Optional.** Icinga Notifications daemon URL. If not set, notifications are disabled |
90+
| NOTIFICATIONS_USERNAME | **Optional.** Username for authenticating the Icinga for Kubernetes source in Icinga Notifications. |
91+
| NOTIFICATIONS_PASSWORD | **Optional.** Password for authenticating the Icinga for Kubernetes source in Icinga Notifications. |
92+
| NOTIFICATIONS_KUBERNETES_WEB_URL | **Optional.** The base URL of Icinga for Kubernetes Web used in generated Icinga Notification events. |
93+
94+
## Prometheus Configuration
95+
96+
| Env | Description |
97+
|---------------------|----------------------------------------------------------------------------------------------------------------------------|
98+
| PROMETHEUS_URL | **Optional.** Prometheus server URL. If not set, metric synchronization is disabled. |
99+
| PROMETHEUS_INSECURE | **Optional.** Skip the TLS/SSL certificate verification. Can be set to 'true' or 'false'. If not set, defaults to 'false'. |
100+
| PROMETHEUS_USERNAME | **Optional.** Prometheus username. |
101+
| PROMETHEUS_PASSWORD | **Optional.** Prometheus password. |

go.mod

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module github.com/icinga/icinga-kubernetes
22

3-
go 1.22.0
3+
go 1.23.0
44

55
require (
66
github.com/go-co-op/gocron v1.37.0
77
github.com/go-logr/logr v1.4.2
8-
github.com/go-sql-driver/mysql v1.8.1
8+
github.com/go-sql-driver/mysql v1.9.2
99
github.com/google/uuid v1.6.0
10-
github.com/icinga/icinga-go-library v0.3.2-0.20241118194934-1a19cd696d37
10+
github.com/icinga/icinga-go-library v0.6.4-0.20250519095646-5a1c5090f238
1111
github.com/jmoiron/sqlx v1.4.0
1212
github.com/lib/pq v1.10.9
1313
github.com/okzk/sdnotify v0.0.0-20240725214427-1c1fdd37c5ac
@@ -17,7 +17,7 @@ require (
1717
github.com/spf13/pflag v1.0.5
1818
go.uber.org/zap v1.27.0
1919
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
20-
golang.org/x/sync v0.9.0
20+
golang.org/x/sync v0.14.0
2121
k8s.io/api v0.31.1
2222
k8s.io/apimachinery v0.31.1
2323
k8s.io/client-go v0.31.1
@@ -27,7 +27,7 @@ require (
2727

2828
require (
2929
filippo.io/edwards25519 v1.1.0 // indirect
30-
github.com/caarlos0/env/v11 v11.2.2 // indirect
30+
github.com/caarlos0/env/v11 v11.3.1 // indirect
3131
github.com/creasty/defaults v1.8.0 // indirect
3232
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
3333
github.com/emicklei/go-restful/v3 v3.12.1 // indirect

go.sum

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
22
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
33
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
44
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5-
github.com/caarlos0/env/v11 v11.2.2 h1:95fApNrUyueipoZN/EhA8mMxiNxrBwDa+oAZrMWl3Kg=
6-
github.com/caarlos0/env/v11 v11.2.2/go.mod h1:JBfcdeQiBoI3Zh1QRAWfe+tpiNTmDtcCj/hHHHMx0vc=
5+
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
6+
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
77
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
88
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
99
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -37,8 +37,9 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
3737
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
3838
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
3939
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
40-
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
4140
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
41+
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
42+
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
4243
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
4344
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
4445
github.com/goccy/go-yaml v1.13.0 h1:0Wtp0FZLd7Sm8gERmR9S6Iczzb3vItJj7NaHmFg8pTs=
@@ -60,8 +61,8 @@ github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73
6061
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6162
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
6263
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
63-
github.com/icinga/icinga-go-library v0.3.2-0.20241118194934-1a19cd696d37 h1:b1xWtyFSPlCBTgP7sajx4fb+zecPh0LOXnXsJ7n3r9o=
64-
github.com/icinga/icinga-go-library v0.3.2-0.20241118194934-1a19cd696d37/go.mod h1:zBVLixVxt+FIxOct/DDTBzbu02BlvPZ0Mhcq8t6ErxE=
64+
github.com/icinga/icinga-go-library v0.6.4-0.20250519095646-5a1c5090f238 h1:oyg/IjB+brEQcW7d2uKU4vjPoEUYctQ4chttZnTSQh4=
65+
github.com/icinga/icinga-go-library v0.6.4-0.20250519095646-5a1c5090f238/go.mod h1:WrbqJ6DW8SFbYZWWd1/pi35dNHLCjavXI6VdSSPL7Z4=
6566
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
6667
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
6768
github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
@@ -144,8 +145,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
144145
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
145146
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
146147
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
147-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
148-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
148+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
149+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
149150
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
150151
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
151152
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -179,8 +180,8 @@ golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
179180
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
180181
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
181182
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
182-
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
183-
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
183+
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
184+
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
184185
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
185186
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
186187
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pkg/daemon/config.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ import (
77
"github.com/icinga/icinga-kubernetes/pkg/notifications"
88
)
99

10+
// DefaultConfigPath specifies the default location of Icinga for Kubernetes's config.yml
11+
// if not set via command line flag.
12+
const DefaultConfigPath = "./config.yml"
13+
1014
// Config defines Icinga Kubernetes config.
1115
type Config struct {
12-
Database database.Config `yaml:"database"`
13-
Logging logging.Config `yaml:"logging"`
14-
Notifications notifications.Config `yaml:"notifications"`
15-
Prometheus metrics.PrometheusConfig `yaml:"prometheus"`
16+
Database database.Config `yaml:"database" envPrefix:"DATABASE_"`
17+
Logging logging.Config `yaml:"logging" envPrefix:"LOGGING_"`
18+
Notifications notifications.Config `yaml:"notifications" envPrefix:"NOTIFICATIONS_"`
19+
Prometheus metrics.PrometheusConfig `yaml:"prometheus" envPrefix:"PROMETHEUS_"`
1620
}
1721

1822
// Validate checks constraints in the supplied configuration and returns an error if they are violated.
@@ -31,3 +35,26 @@ func (c *Config) Validate() error {
3135

3236
return c.Notifications.Validate()
3337
}
38+
39+
// ConfigFlagGlue provides a glue struct for the CLI config flag.
40+
//
41+
// ConfigFlagGlue implements the [github.com/icinga/icinga-go-library/config.Flags] interface.
42+
type ConfigFlagGlue struct {
43+
// Config is the path to the config file
44+
Config string
45+
}
46+
47+
// GetConfigPath retrieves the path to the configuration file.
48+
// It returns the path specified via the command line, or DefaultConfigPath if none is provided.
49+
func (f ConfigFlagGlue) GetConfigPath() string {
50+
if f.Config == "" {
51+
return DefaultConfigPath
52+
}
53+
54+
return f.Config
55+
}
56+
57+
// IsExplicitConfigPath indicates whether the configuration file path was explicitly set.
58+
func (f ConfigFlagGlue) IsExplicitConfigPath() bool {
59+
return f.Config != ""
60+
}

pkg/metrics/config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import (
66

77
// PrometheusConfig defines Prometheus configuration.
88
type PrometheusConfig struct {
9-
Url string `yaml:"url"`
10-
Insecure string `yaml:"insecure"`
11-
Username string `yaml:"username"`
12-
Password string `yaml:"password"`
9+
Url string `yaml:"url" env:"URL"`
10+
Insecure string `yaml:"insecure" env:"INSECURE"`
11+
Username string `yaml:"username" env:"USERNAME"`
12+
Password string `yaml:"password" env:"PASSWORD"`
1313
}
1414

1515
// Validate checks constraints in the supplied Prometheus configuration and returns an error if they are violated.

0 commit comments

Comments
 (0)