mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-07 21:46:37 +00:00
feat: Add config file validation (#2011)
This commit is contained in:
@@ -19,6 +19,7 @@ linters:
|
||||
- maintidx
|
||||
- mnd
|
||||
- paralleltest
|
||||
- tagliatelle
|
||||
- testpackage
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
const Name = "dfsr"
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"sources-enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -41,7 +41,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -38,7 +38,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -46,7 +46,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
const Name = "filetime"
|
||||
|
||||
type Config struct {
|
||||
FilePatterns []string
|
||||
FilePatterns []string `yaml:"file-patterns"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -52,7 +52,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -35,10 +35,10 @@ import (
|
||||
const Name = "iis"
|
||||
|
||||
type Config struct {
|
||||
SiteInclude *regexp.Regexp `yaml:"site_include"`
|
||||
SiteExclude *regexp.Regexp `yaml:"site_exclude"`
|
||||
AppInclude *regexp.Regexp `yaml:"app_include"`
|
||||
AppExclude *regexp.Regexp `yaml:"app_exclude"`
|
||||
SiteInclude *regexp.Regexp `yaml:"site-include"`
|
||||
SiteExclude *regexp.Regexp `yaml:"site-exclude"`
|
||||
AppInclude *regexp.Regexp `yaml:"app-include"`
|
||||
AppExclude *regexp.Regexp `yaml:"app-exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -38,8 +38,8 @@ import (
|
||||
const Name = "logical_disk"
|
||||
|
||||
type Config struct {
|
||||
VolumeInclude *regexp.Regexp `yaml:"volume_include"`
|
||||
VolumeExclude *regexp.Regexp `yaml:"volume_exclude"`
|
||||
VolumeInclude *regexp.Regexp `yaml:"volume-include"`
|
||||
VolumeExclude *regexp.Regexp `yaml:"volume-exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -41,7 +41,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -54,7 +54,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -43,9 +43,9 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
NicExclude *regexp.Regexp `yaml:"nic_exclude"`
|
||||
NicInclude *regexp.Regexp `yaml:"nic_include"`
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
NicExclude *regexp.Regexp `yaml:"nic-exclude"`
|
||||
NicInclude *regexp.Regexp `yaml:"nic-include"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
const Name = "netframework"
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -19,6 +19,7 @@ package performancecounter
|
||||
|
||||
import (
|
||||
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Object struct {
|
||||
@@ -41,3 +42,7 @@ type Counter struct {
|
||||
}
|
||||
|
||||
// https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/54691ebe11bb9ec32b4e35cd31fcb94a352de134/receiver/windowsperfcountersreceiver/README.md?plain=1#L150
|
||||
|
||||
func (*Config) UnmarshalYAML(*yaml.Node) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ import (
|
||||
const Name = "physical_disk"
|
||||
|
||||
type Config struct {
|
||||
DiskInclude *regexp.Regexp `yaml:"disk_include"`
|
||||
DiskExclude *regexp.Regexp `yaml:"disk_exclude"`
|
||||
DiskInclude *regexp.Regexp `yaml:"disk-include"`
|
||||
DiskExclude *regexp.Regexp `yaml:"disk-exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -46,8 +46,8 @@ var printerStatusMap = map[uint16]string{
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
PrinterInclude *regexp.Regexp `yaml:"printer_include"`
|
||||
PrinterExclude *regexp.Regexp `yaml:"printer_exclude"`
|
||||
PrinterInclude *regexp.Regexp `yaml:"include"`
|
||||
PrinterExclude *regexp.Regexp `yaml:"exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -39,9 +39,9 @@ import (
|
||||
const Name = "process"
|
||||
|
||||
type Config struct {
|
||||
ProcessInclude *regexp.Regexp `yaml:"process_include"`
|
||||
ProcessExclude *regexp.Regexp `yaml:"process_exclude"`
|
||||
EnableWorkerProcess bool `yaml:"enable_iis_worker_process"` //nolint:tagliatelle
|
||||
ProcessInclude *regexp.Regexp `yaml:"include"`
|
||||
ProcessExclude *regexp.Regexp `yaml:"exclude"`
|
||||
EnableWorkerProcess bool `yaml:"iis"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -36,8 +36,8 @@ import (
|
||||
const Name = "scheduled_task"
|
||||
|
||||
type Config struct {
|
||||
TaskExclude *regexp.Regexp `yaml:"task_exclude"`
|
||||
TaskInclude *regexp.Regexp `yaml:"task_include"`
|
||||
TaskExclude *regexp.Regexp `yaml:"exclude"`
|
||||
TaskInclude *regexp.Regexp `yaml:"include"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -38,8 +38,8 @@ import (
|
||||
const Name = "service"
|
||||
|
||||
type Config struct {
|
||||
ServiceInclude *regexp.Regexp `yaml:"service_include"`
|
||||
ServiceExclude *regexp.Regexp `yaml:"service_exclude"`
|
||||
ServiceInclude *regexp.Regexp `yaml:"include"`
|
||||
ServiceExclude *regexp.Regexp `yaml:"exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -32,8 +32,8 @@ import (
|
||||
const Name = "smtp"
|
||||
|
||||
type Config struct {
|
||||
ServerInclude *regexp.Regexp `yaml:"server_include"`
|
||||
ServerExclude *regexp.Regexp `yaml:"server_exclude"`
|
||||
ServerInclude *regexp.Regexp `yaml:"server-include"`
|
||||
ServerExclude *regexp.Regexp `yaml:"server-exclude"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
const Name = "tcp"
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -41,7 +41,7 @@ import (
|
||||
const Name = "textfile"
|
||||
|
||||
type Config struct {
|
||||
TextFileDirectories []string `yaml:"text_file_directories"`
|
||||
TextFileDirectories []string `yaml:"directories"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -43,7 +43,7 @@ const (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CollectorsEnabled []string `yaml:"collectors_enabled"`
|
||||
CollectorsEnabled []string `yaml:"enabled"`
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
|
||||
@@ -19,13 +19,49 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/windows_exporter/pkg/collector"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// configFile represents the structure of the windows_exporter configuration file,
|
||||
// including configuration from the collector and web packages.
|
||||
type configFile struct {
|
||||
Debug struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
} `yaml:"debug"`
|
||||
Collectors struct {
|
||||
Enabled string `yaml:"enabled"`
|
||||
} `yaml:"collectors"`
|
||||
Collector collector.Config `yaml:"collector"`
|
||||
Log struct {
|
||||
Level string `yaml:"level"`
|
||||
Format string `yaml:"format"`
|
||||
File string `yaml:"file"`
|
||||
} `yaml:"log"`
|
||||
Process struct {
|
||||
Priority string `yaml:"priority"`
|
||||
MemoryLimit string `yaml:"memory-limit"`
|
||||
} `yaml:"process"`
|
||||
Scrape struct {
|
||||
TimeoutMargin string `yaml:"timeout-margin"`
|
||||
} `yaml:"scrape"`
|
||||
Telemetry struct {
|
||||
Path string `yaml:"path"`
|
||||
} `yaml:"telemetry"`
|
||||
Web struct {
|
||||
DisableExporterMetrics bool `yaml:"disable-exporter-metrics"`
|
||||
ListenAddresses any `yaml:"listen-address"`
|
||||
Config struct {
|
||||
File string `yaml:"file"`
|
||||
} `yaml:"config"`
|
||||
} `yaml:"web"`
|
||||
}
|
||||
|
||||
type getFlagger interface {
|
||||
GetFlag(name string) *kingpin.FlagClause
|
||||
}
|
||||
@@ -80,24 +116,37 @@ func ParseConfigFile(args []string) string {
|
||||
}
|
||||
|
||||
// NewConfigFileResolver returns a Resolver structure.
|
||||
func NewConfigFileResolver(file string) (*Resolver, error) {
|
||||
func NewConfigFileResolver(filePath string) (*Resolver, error) {
|
||||
flags := map[string]string{}
|
||||
|
||||
var (
|
||||
err error
|
||||
fileBytes []byte
|
||||
)
|
||||
|
||||
fileBytes, err = readFromFile(file)
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("failed to open configuration file: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
var configFileStructure configFile
|
||||
|
||||
decoder := yaml.NewDecoder(file)
|
||||
decoder.KnownFields(true)
|
||||
|
||||
if err = decoder.Decode(&configFileStructure); err != nil {
|
||||
return nil, fmt.Errorf("configuration file validation error: %w", err)
|
||||
}
|
||||
|
||||
_, err = file.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to rewind file: %w", err)
|
||||
}
|
||||
|
||||
var rawValues map[string]interface{}
|
||||
|
||||
err = yaml.Unmarshal(fileBytes, &rawValues)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal configuration file: %w", err)
|
||||
decoder = yaml.NewDecoder(file)
|
||||
if err = decoder.Decode(&rawValues); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse configuration file: %w", err)
|
||||
}
|
||||
|
||||
// Flatten nested YAML values
|
||||
@@ -111,23 +160,9 @@ func NewConfigFileResolver(file string) (*Resolver, error) {
|
||||
return &Resolver{flags: flags}, nil
|
||||
}
|
||||
|
||||
func readFromFile(file string) ([]byte, error) {
|
||||
if _, err := os.Stat(file); err != nil {
|
||||
return nil, fmt.Errorf("failed to read configuration file: %w", err)
|
||||
}
|
||||
|
||||
fileBytes, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read configuration file: %w", err)
|
||||
}
|
||||
|
||||
return fileBytes, nil
|
||||
}
|
||||
|
||||
func (c *Resolver) setDefault(v getFlagger) {
|
||||
for name, value := range c.flags {
|
||||
f := v.GetFlag(name)
|
||||
if f != nil {
|
||||
if f := v.GetFlag(name); f != nil {
|
||||
f.Default(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,26 +79,26 @@ type Config struct {
|
||||
Cs cs.Config `yaml:"cs"`
|
||||
DFSR dfsr.Config `yaml:"dfsr"`
|
||||
Dhcp dhcp.Config `yaml:"dhcp"`
|
||||
DiskDrive diskdrive.Config `yaml:"disk_drive"`
|
||||
DiskDrive diskdrive.Config `yaml:"diskdrive"`
|
||||
DNS dns.Config `yaml:"dns"`
|
||||
Exchange exchange.Config `yaml:"exchange"`
|
||||
Filetime filetime.Config `yaml:"filetime"`
|
||||
Fsrmquota fsrmquota.Config `yaml:"fsrmquota"`
|
||||
HyperV hyperv.Config `yaml:"hyper_v"`
|
||||
HyperV hyperv.Config `yaml:"hyperv"`
|
||||
IIS iis.Config `yaml:"iis"`
|
||||
License license.Config `yaml:"license"`
|
||||
LogicalDisk logical_disk.Config `yaml:"logical_disk"`
|
||||
Logon logon.Config `yaml:"logon"`
|
||||
Memory memory.Config `yaml:"memory"`
|
||||
MSCluster mscluster.Config `yaml:"ms_cluster"`
|
||||
MSCluster mscluster.Config `yaml:"mscluster"`
|
||||
Msmq msmq.Config `yaml:"msmq"`
|
||||
Mssql mssql.Config `yaml:"mssql"`
|
||||
Net net.Config `yaml:"net"`
|
||||
NetFramework netframework.Config `yaml:"net_framework"`
|
||||
NetFramework netframework.Config `yaml:"netframework"`
|
||||
Nps nps.Config `yaml:"nps"`
|
||||
OS os.Config `yaml:"os"`
|
||||
Paging pagefile.Config `yaml:"paging"`
|
||||
PerformanceCounter performancecounter.Config `yaml:"performance_counter"`
|
||||
PerformanceCounter performancecounter.Config `yaml:"performancecounter"`
|
||||
PhysicalDisk physical_disk.Config `yaml:"physical_disk"`
|
||||
Printer printer.Config `yaml:"printer"`
|
||||
Process process.Config `yaml:"process"`
|
||||
@@ -112,7 +112,7 @@ type Config struct {
|
||||
TCP tcp.Config `yaml:"tcp"`
|
||||
TerminalServices terminal_services.Config `yaml:"terminal_services"`
|
||||
Textfile textfile.Config `yaml:"textfile"`
|
||||
ThermalZone thermalzone.Config `yaml:"thermal_zone"`
|
||||
ThermalZone thermalzone.Config `yaml:"thermalzone"`
|
||||
Time time.Config `yaml:"time"`
|
||||
UDP udp.Config `yaml:"udp"`
|
||||
Update update.Config `yaml:"update"`
|
||||
|
||||
Reference in New Issue
Block a user