Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

Merge pull request #245286 from codec/add-prometheus-idrac-exporter

prometheus-idrac-exporter: init at unstable-2023-06-29

authored by Franz Pletz and committed by GitHub 8e372c19 186c0b28

+238 -1
+6
maintainers/maintainer-list.nix
··· 3265 3265 fingerprint = "6E3A FA6D 915C C2A4 D26F C53E 7BB4 BA9C 783D 2BBC"; 3266 3266 }]; 3267 3267 }; 3268 + codec = { 3269 + email = "codec@fnord.cx"; 3270 + github = "codec"; 3271 + githubId = 118829; 3272 + name = "codec"; 3273 + }; 3268 3274 CodeLongAndProsper90 = { 3269 3275 github = "CodeLongAndProsper90"; 3270 3276 githubId = 50145141;
+15 -1
nixos/modules/services/monitoring/prometheus/exporters.nix
··· 36 36 "fastly" 37 37 "fritzbox" 38 38 "graphite" 39 + "idrac" 39 40 "influxdb" 40 41 "ipmi" 41 42 "json" ··· 318 319 message = '' 319 320 Scaphandre needs 'intel_rapl_common' kernel module to be enabled. Please add it in 'boot.kernelModules'. 320 321 ''; 322 + } { 323 + assertion = cfg.idrac.enable -> ( 324 + (cfg.idrac.configurationPath == null) != (cfg.idrac.configuration == null) 325 + ); 326 + message = '' 327 + Please ensure you have either `services.prometheus.exporters.idrac.configuration' 328 + or `services.prometheus.exporters.idrac.configurationPath' set! 329 + ''; 321 330 } ] ++ (flip map (attrNames exporterOpts) (exporter: { 322 331 assertion = cfg.${exporter}.firewallFilter != null -> cfg.${exporter}.openFirewall; 323 332 message = '' ··· 325 334 `openFirewall' is set to `true'! 326 335 ''; 327 336 })) ++ config.services.prometheus.exporters.assertions; 328 - warnings = config.services.prometheus.exporters.warnings; 337 + warnings = [(mkIf (config.services.prometheus.exporters.idrac.enable && config.services.prometheus.exporters.idrac.configurationPath != null) '' 338 + Configuration file in `services.prometheus.exporters.idrac.configurationPath` may override 339 + `services.prometheus.exporters.idrac.listenAddress` and/or `services.prometheus.exporters.idrac.port`. 340 + Consider using `services.prometheus.exporters.idrac.configuration` instead. 341 + '' 342 + )] ++ config.services.prometheus.exporters.warnings; 329 343 }] ++ [(mkIf config.services.minio.enable { 330 344 services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000"; 331 345 services.prometheus.exporters.minio.minioAccessKey = mkDefault config.services.minio.accessKey;
+69
nixos/modules/services/monitoring/prometheus/exporters/idrac.nix
··· 1 + { config, lib, pkgs, options }: 2 + 3 + with lib; 4 + let 5 + cfg = config.services.prometheus.exporters.idrac; 6 + 7 + configFile = if cfg.configurationPath != null 8 + then cfg.configurationPath 9 + else pkgs.writeText "idrac.yml" (builtins.toJSON cfg.configuration); 10 + in 11 + { 12 + port = 9348; 13 + extraOpts = { 14 + configurationPath = mkOption { 15 + type = with types; nullOr path; 16 + default = null; 17 + example = "/etc/prometheus-idrac-exporter/idrac.yml"; 18 + description = lib.mdDoc '' 19 + Path to the service's config file. This path can either be a computed path in /nix/store or a path in the local filesystem. 20 + 21 + The config file should NOT be stored in /nix/store as it will contain passwords and/or keys in plain text. 22 + 23 + Mutually exclusive with `configuration` option. 24 + 25 + Configuration reference: https://github.com/mrlhansen/idrac_exporter/#configuration 26 + ''; 27 + }; 28 + configuration = mkOption { 29 + type = types.nullOr types.attrs; 30 + description = lib.mdDoc '' 31 + Configuration for iDRAC exporter, as a nix attribute set. 32 + 33 + Configuration reference: https://github.com/mrlhansen/idrac_exporter/#configuration 34 + 35 + Mutually exclusive with `configurationPath` option. 36 + ''; 37 + default = null; 38 + example = { 39 + timeout = 10; 40 + retries = 1; 41 + hosts = { 42 + default = { 43 + username = "username"; 44 + password = "password"; 45 + }; 46 + }; 47 + metrics = { 48 + system = true; 49 + sensors = true; 50 + power = true; 51 + sel = true; 52 + storage = true; 53 + memory = true; 54 + }; 55 + }; 56 + }; 57 + }; 58 + 59 + serviceOpts = { 60 + serviceConfig = { 61 + LoadCredential = "configFile:${configFile}"; 62 + ExecStart = "${pkgs.prometheus-idrac-exporter}/bin/idrac_exporter -config %d/configFile"; 63 + Environment = [ 64 + "IDRAC_EXPORTER_LISTEN_ADDRESS=${cfg.listenAddress}" 65 + "IDRAC_EXPORTER_LISTEN_PORT=${toString cfg.port}" 66 + ]; 67 + }; 68 + }; 69 + }
+17
nixos/tests/prometheus-exporters.nix
··· 307 307 ''; 308 308 }; 309 309 310 + idrac = { 311 + exporterConfig = { 312 + enable = true; 313 + port = 9348; 314 + configuration = { 315 + hosts = { 316 + default = { username = "username"; password = "password"; }; 317 + }; 318 + }; 319 + }; 320 + exporterTest = '' 321 + wait_for_unit("prometheus-idrac-exporter.service") 322 + wait_for_open_port(9348) 323 + wait_until_succeeds("curl localhost:9348") 324 + ''; 325 + }; 326 + 310 327 influxdb = { 311 328 exporterConfig = { 312 329 enable = true;
+30
pkgs/servers/monitoring/prometheus/idrac-exporter.nix
··· 1 + { lib, buildGoModule, fetchFromGitHub, nixosTests }: 2 + 3 + buildGoModule rec { 4 + pname = "idrac_exporter"; 5 + version = "unstable-2023-06-29"; 6 + 7 + src = fetchFromGitHub { 8 + owner = "mrlhansen"; 9 + repo = "idrac_exporter"; 10 + rev = "3b311e0e6d602fb0938267287f425f341fbf11da"; 11 + sha256 = "sha256-N8wSjQE25TCXg/+JTsvQk3fjTBgfXTiSGHwZWFDmFKc="; 12 + }; 13 + 14 + vendorHash = "sha256-iNV4VrdQONq7LXwAc6AaUROHy8TmmloUAL8EmuPtF/o="; 15 + 16 + patches = [ ./idrac-exporter/config-from-environment.patch ]; 17 + 18 + ldflags = [ "-s" "-w" ]; 19 + 20 + doCheck = true; 21 + 22 + passthru.tests = { inherit (nixosTests.prometheus-exporters) idrac; }; 23 + 24 + meta = with lib; { 25 + inherit (src.meta) homepage; 26 + description = "Simple iDRAC exporter for Prometheus"; 27 + license = licenses.mit; 28 + maintainers = with maintainers; [ codec ]; 29 + }; 30 + }
+100
pkgs/servers/monitoring/prometheus/idrac-exporter/config-from-environment.patch
··· 1 + diff --git a/internal/config/config.go b/internal/config/config.go 2 + index ba8f066..1c801cd 100644 3 + --- a/internal/config/config.go 4 + +++ b/internal/config/config.go 5 + @@ -2,8 +2,11 @@ package config 6 + 7 + import ( 8 + "encoding/base64" 9 + + "fmt" 10 + "os" 11 + + "strconv" 12 + "sync" 13 + + 14 + "github.com/mrlhansen/idrac_exporter/internal/logging" 15 + "gopkg.in/yaml.v2" 16 + ) 17 + @@ -17,9 +20,9 @@ type HostConfig struct { 18 + 19 + type RootConfig struct { 20 + mutex sync.Mutex 21 + - Address string `yaml:"address"` 22 + - Port uint `yaml:"port"` 23 + - MetricsPrefix string `yaml:"metrics_prefix"` 24 + + Address string `yaml:"address"` 25 + + Port uint `yaml:"port"` 26 + + MetricsPrefix string `yaml:"metrics_prefix"` 27 + Collect struct { 28 + System bool `yaml:"system"` 29 + Sensors bool `yaml:"sensors"` 30 + @@ -28,9 +31,29 @@ type RootConfig struct { 31 + Storage bool `yaml:"storage"` 32 + Memory bool `yaml:"memory"` 33 + } `yaml:"metrics"` 34 + - Timeout uint `yaml:"timeout"` 35 + - Retries uint `yaml:"retries"` 36 + - Hosts map[string]*HostConfig `yaml:"hosts"` 37 + + Timeout uint `yaml:"timeout"` 38 + + Retries uint `yaml:"retries"` 39 + + Hosts map[string]*HostConfig `yaml:"hosts"` 40 + +} 41 + + 42 + +func getEnv(envvar string, defvalue string) string { 43 + + value := os.Getenv(envvar) 44 + + if len(value) == 0 { 45 + + return defvalue 46 + + } 47 + + return value 48 + +} 49 + + 50 + +func getEnvUint(envvar string, defvalue uint) uint { 51 + + value, err := strconv.Atoi(getEnv(envvar, fmt.Sprint(defvalue))) 52 + + if err != nil { 53 + + logging.Fatalf("Failed parse integer value: %s", err) 54 + + } 55 + + if value == 0 { 56 + + return defvalue 57 + + } 58 + + 59 + + return uint(value) 60 + } 61 + 62 + func (config *RootConfig) GetHostCfg(target string) *HostConfig { 63 + @@ -70,29 +93,29 @@ func ReadConfigFile(fileName string) { 64 + } 65 + 66 + if Config.Address == "" { 67 + - Config.Address = "0.0.0.0" 68 + + Config.Address = getEnv("IDRAC_EXPORTER_LISTEN_ADDRESS", "0.0.0.0") 69 + } 70 + 71 + if Config.Port == 0 { 72 + - Config.Port = 9348 73 + + Config.Port = getEnvUint("IDRAC_EXPORTER_LISTEN_PORT", 9348) 74 + } 75 + 76 + if Config.Timeout == 0 { 77 + - Config.Timeout = 10 78 + + Config.Timeout = getEnvUint("IDRAC_EXPORTER_TIMEOUT", 10) 79 + } 80 + 81 + if Config.Retries == 0 { 82 + - Config.Retries = 1 83 + + Config.Retries = getEnvUint("IDRAC_EXPORTER_RETRIES", 1) 84 + + } 85 + + 86 + + if Config.MetricsPrefix == "" { 87 + + Config.MetricsPrefix = getEnv("IDRAC_EXPORTER_PREFIX", "idrac") 88 + } 89 + 90 + if len(Config.Hosts) == 0 { 91 + parseError("missing section", "hosts") 92 + } 93 + 94 + - if Config.MetricsPrefix == "" { 95 + - Config.MetricsPrefix = "idrac" 96 + - } 97 + - 98 + for k, v := range Config.Hosts { 99 + if v.Username == "" { 100 + parseError("missing username for host", k)
+1
pkgs/top-level/all-packages.nix
··· 26935 26935 prometheus-gitlab-ci-pipelines-exporter = callPackage ../servers/monitoring/prometheus/gitlab-ci-pipelines-exporter.nix { }; 26936 26936 prometheus-graphite-exporter = callPackage ../servers/monitoring/prometheus/graphite-exporter.nix { }; 26937 26937 prometheus-haproxy-exporter = callPackage ../servers/monitoring/prometheus/haproxy-exporter.nix { }; 26938 + prometheus-idrac-exporter = callPackage ../servers/monitoring/prometheus/idrac-exporter.nix { }; 26938 26939 prometheus-influxdb-exporter = callPackage ../servers/monitoring/prometheus/influxdb-exporter.nix { }; 26939 26940 prometheus-ipmi-exporter = callPackage ../servers/monitoring/prometheus/ipmi-exporter.nix { }; 26940 26941 prometheus-jitsi-exporter = callPackage ../servers/monitoring/prometheus/jitsi-exporter.nix { };