@@ -6,7 +6,9 @@ package config
6
6
import (
7
7
"fmt"
8
8
"io"
9
+ "net"
9
10
"os"
11
+ "strconv"
10
12
"strings"
11
13
"time"
12
14
39
41
} `yaml:"fake-cpu-meter"`
40
42
}
41
43
Web struct {
42
- Config string `yaml:"configFile"`
44
+ Config string `yaml:"configFile"`
45
+ ListenAddresses []string `yaml:"listenAddresses"`
43
46
}
44
47
45
48
Monitor struct {
@@ -157,7 +160,8 @@ const (
157
160
158
161
pprofEnabledFlag = "debug.pprof"
159
162
160
- WebConfigFlag = "web.config-file"
163
+ WebConfigFlag = "web.config-file"
164
+ WebListenAddressFlag = "web.listen-address"
161
165
162
166
// Exporters
163
167
ExporterStdoutEnabledFlag = "exporter.stdout"
@@ -210,6 +214,9 @@ func DefaultConfig() *Config {
210
214
Enabled : ptr .To (false ),
211
215
},
212
216
},
217
+ Web : Web {
218
+ ListenAddresses : []string {":28282" },
219
+ },
213
220
Kube : Kube {
214
221
Enabled : ptr .To (false ),
215
222
},
@@ -295,6 +302,7 @@ func RegisterFlags(app *kingpin.Application) ConfigUpdaterFn {
295
302
296
303
enablePprof := app .Flag (pprofEnabledFlag , "Enable pprof debug endpoints" ).Default ("false" ).Bool ()
297
304
webConfig := app .Flag (WebConfigFlag , "Web config file path" ).Default ("" ).String ()
305
+ webListenAddresses := app .Flag (WebListenAddressFlag , "Web server listen addresses" ).Default (":28282" ).Strings ()
298
306
299
307
// exporters
300
308
stdoutExporterEnabled := app .Flag (ExporterStdoutEnabledFlag , "Enable stdout exporter" ).Default ("false" ).Bool ()
@@ -343,6 +351,10 @@ func RegisterFlags(app *kingpin.Application) ConfigUpdaterFn {
343
351
cfg .Web .Config = * webConfig
344
352
}
345
353
354
+ if flagsSet [WebListenAddressFlag ] {
355
+ cfg .Web .ListenAddresses = * webListenAddresses
356
+ }
357
+
346
358
if flagsSet [ExporterStdoutEnabledFlag ] {
347
359
cfg .Exporter .Stdout .Enabled = stdoutExporterEnabled
348
360
}
@@ -378,6 +390,9 @@ func (c *Config) sanitize() {
378
390
c .Host .SysFS = strings .TrimSpace (c .Host .SysFS )
379
391
c .Host .ProcFS = strings .TrimSpace (c .Host .ProcFS )
380
392
c .Web .Config = strings .TrimSpace (c .Web .Config )
393
+ for i := range c .Web .ListenAddresses {
394
+ c .Web .ListenAddresses [i ] = strings .TrimSpace (c .Web .ListenAddresses [i ])
395
+ }
381
396
382
397
for i := range c .Rapl .Zones {
383
398
c .Rapl .Zones [i ] = strings .TrimSpace (c .Rapl .Zones [i ])
@@ -437,6 +452,20 @@ func (c *Config) Validate(skips ...SkipValidation) error {
437
452
}
438
453
}
439
454
}
455
+ { // Web listen addresses
456
+ if len (c .Web .ListenAddresses ) == 0 {
457
+ errs = append (errs , "at least one web listen address must be specified" )
458
+ }
459
+ for _ , addr := range c .Web .ListenAddresses {
460
+ if addr == "" {
461
+ errs = append (errs , "web listen address cannot be empty" )
462
+ continue
463
+ }
464
+ if err := validateListenAddress (addr ); err != nil {
465
+ errs = append (errs , fmt .Sprintf ("invalid web listen address %q: %s" , addr , err .Error ()))
466
+ }
467
+ }
468
+ }
440
469
{ // Monitor
441
470
if c .Monitor .Interval < 0 {
442
471
errs = append (errs , fmt .Sprintf ("invalid monitor interval: %s can't be negative" , c .Monitor .Interval ))
@@ -506,6 +535,37 @@ func canReadFile(path string) error {
506
535
return nil
507
536
}
508
537
538
+ func validateListenAddress (addr string ) error {
539
+ if addr == "" {
540
+ return fmt .Errorf ("address cannot be empty" )
541
+ }
542
+
543
+ // Use Go's standard library to parse host:port
544
+ _ , port , err := net .SplitHostPort (addr )
545
+ if err != nil {
546
+ return fmt .Errorf ("invalid address format: %w" , err )
547
+ }
548
+
549
+ // Validate port (host can be empty for listening on all interfaces)
550
+ if err := validatePort (port ); err != nil {
551
+ return err
552
+ }
553
+
554
+ return nil
555
+ }
556
+
557
+ func validatePort (port string ) error {
558
+ portNum , err := strconv .Atoi (port )
559
+ if err != nil {
560
+ return fmt .Errorf ("port must be numeric, got %s" , port )
561
+ }
562
+
563
+ if portNum < 1 || portNum > 65535 {
564
+ return fmt .Errorf ("port must be between 1 and 65535, got %d" , portNum )
565
+ }
566
+ return nil
567
+ }
568
+
509
569
func (c * Config ) String () string {
510
570
bytes , err := yaml .Marshal (c )
511
571
if err == nil {
0 commit comments