1// Copyright The OpenTelemetry Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package hostmetricsreceiver
16
17import (
18	"errors"
19	"fmt"
20
21	"github.com/spf13/cast"
22
23	"go.opentelemetry.io/collector/config"
24	"go.opentelemetry.io/collector/config/configparser"
25	"go.opentelemetry.io/collector/receiver/hostmetricsreceiver/internal"
26	"go.opentelemetry.io/collector/receiver/scraperhelper"
27)
28
29const (
30	scrapersKey = "scrapers"
31)
32
33// Config defines configuration for HostMetrics receiver.
34type Config struct {
35	scraperhelper.ScraperControllerSettings `mapstructure:",squash"`
36	Scrapers                                map[string]internal.Config `mapstructure:"-"`
37}
38
39var _ config.Receiver = (*Config)(nil)
40var _ config.CustomUnmarshable = (*Config)(nil)
41
42// Validate checks the receiver configuration is valid
43func (cfg *Config) Validate() error {
44	if len(cfg.Scrapers) == 0 {
45		return errors.New("must specify at least one scraper when using hostmetrics receiver")
46	}
47
48	return nil
49}
50
51// Unmarshal a config.Parser into the config struct.
52func (cfg *Config) Unmarshal(componentParser *configparser.Parser) error {
53	if componentParser == nil {
54		return nil
55	}
56
57	// load the non-dynamic config normally
58	err := componentParser.Unmarshal(cfg)
59	if err != nil {
60		return err
61	}
62
63	// dynamically load the individual collector configs based on the key name
64
65	cfg.Scrapers = map[string]internal.Config{}
66
67	scrapersSection, err := componentParser.Sub(scrapersKey)
68	if err != nil {
69		return err
70	}
71
72	for key := range cast.ToStringMap(componentParser.Get(scrapersKey)) {
73		factory, ok := getScraperFactory(key)
74		if !ok {
75			return fmt.Errorf("invalid scraper key: %s", key)
76		}
77
78		collectorCfg := factory.CreateDefaultConfig()
79		collectorViperSection, err := scrapersSection.Sub(key)
80		if err != nil {
81			return err
82		}
83		err = collectorViperSection.UnmarshalExact(collectorCfg)
84		if err != nil {
85			return fmt.Errorf("error reading settings for scraper type %q: %v", key, err)
86		}
87
88		cfg.Scrapers[key] = collectorCfg
89	}
90
91	return nil
92}
93