diff --git a/config/config.go b/config/config.go index 36847d045f..079d546a6b 100644 --- a/config/config.go +++ b/config/config.go @@ -792,6 +792,7 @@ func (c *MarathonSDConfig) UnmarshalYAML(unmarshal func(interface{}) error) erro // KubernetesSDConfig is the configuration for Kubernetes service discovery. type KubernetesSDConfig struct { APIServers []URL `yaml:"api_servers"` + Role string `yaml:"role"` InCluster bool `yaml:"in_cluster,omitempty"` BasicAuth *BasicAuth `yaml:"basic_auth,omitempty"` BearerToken string `yaml:"bearer_token,omitempty"` @@ -804,6 +805,29 @@ type KubernetesSDConfig struct { XXX map[string]interface{} `yaml:",inline"` } +type KubernetesRole string + +const ( + KubernetesRoleNode = "node" + KubernetesRolePod = "pod" + KubernetesRoleContainer = "container" + KubernetesRoleService = "service" + KubernetesRoleEndpoint = "endpoint" + KubernetesRoleAPIServer = "apiserver" +) + +func (c *KubernetesRole) UnmarshalYAML(unmarshal func(interface{}) error) error { + if err := unmarshal((*string)(c)); err != nil { + return err + } + switch *c { + case KubernetesRoleNode, KubernetesRolePod, KubernetesRoleContainer, KubernetesRoleService, KubernetesRoleEndpoint, KubernetesRoleAPIServer: + return nil + default: + return fmt.Errorf("Unknown Kubernetes SD role %q", c) + } +} + // UnmarshalYAML implements the yaml.Unmarshaler interface. func (c *KubernetesSDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { *c = DefaultKubernetesSDConfig @@ -815,6 +839,9 @@ func (c *KubernetesSDConfig) UnmarshalYAML(unmarshal func(interface{}) error) er if err := checkOverflow(c.XXX, "kubernetes_sd_config"); err != nil { return err } + if c.Role == "" { + return fmt.Errorf("role missing (one of: container, pod, service, endpoint, node, apiserver)") + } if len(c.APIServers) == 0 { return fmt.Errorf("Kubernetes SD configuration requires at least one Kubernetes API server") } @@ -824,7 +851,6 @@ func (c *KubernetesSDConfig) UnmarshalYAML(unmarshal func(interface{}) error) er if c.BasicAuth != nil && (len(c.BearerToken) > 0 || len(c.BearerTokenFile) > 0) { return fmt.Errorf("at most one of basic_auth, bearer_token & bearer_token_file must be configured") } - return nil } diff --git a/config/config_test.go b/config/config_test.go index a7555d8784..ca9ab86a78 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -223,6 +223,7 @@ var expectedConf = &Config{ KubernetesSDConfigs: []*KubernetesSDConfig{ { APIServers: []URL{kubernetesSDHostURL()}, + Role: KubernetesRoleEndpoint, BasicAuth: &BasicAuth{ Username: "myusername", Password: "mypassword", diff --git a/config/testdata/conf.good.yml b/config/testdata/conf.good.yml index b911db7673..ea9acfbf1e 100644 --- a/config/testdata/conf.good.yml +++ b/config/testdata/conf.good.yml @@ -109,7 +109,8 @@ scrape_configs: - job_name: service-kubernetes kubernetes_sd_configs: - - api_servers: + - role: endpoint + api_servers: - 'https://localhost:1234' basic_auth: diff --git a/config/testdata/kubernetes_bearertoken.bad.yml b/config/testdata/kubernetes_bearertoken.bad.yml index 756644be6f..533742fd3f 100644 --- a/config/testdata/kubernetes_bearertoken.bad.yml +++ b/config/testdata/kubernetes_bearertoken.bad.yml @@ -2,7 +2,8 @@ scrape_configs: - job_name: prometheus kubernetes_sd_configs: - - api_servers: + - role: node + api_servers: - 'https://localhost:1234' bearer_token: 1234 diff --git a/config/testdata/kubernetes_bearertoken_basicauth.bad.yml b/config/testdata/kubernetes_bearertoken_basicauth.bad.yml index 9ef16ae4bd..e7c1633d5c 100644 --- a/config/testdata/kubernetes_bearertoken_basicauth.bad.yml +++ b/config/testdata/kubernetes_bearertoken_basicauth.bad.yml @@ -2,7 +2,8 @@ scrape_configs: - job_name: prometheus kubernetes_sd_configs: - - api_servers: + - role: pod + api_servers: - 'https://localhost:1234' bearer_token: 1234 diff --git a/retrieval/discovery/kubernetes/discovery.go b/retrieval/discovery/kubernetes/discovery.go index 1e2a6698b3..d06411d679 100644 --- a/retrieval/discovery/kubernetes/discovery.go +++ b/retrieval/discovery/kubernetes/discovery.go @@ -127,52 +127,35 @@ func (kd *Discovery) Run(ctx context.Context, ch chan<- []*config.TargetGroup) { log.Debugf("Kubernetes Discovery.Run beginning") defer close(ch) - var wg sync.WaitGroup - - pd := &podDiscovery{ - retryInterval: time.Duration(kd.Conf.RetryInterval), - kd: kd, - } - wg.Add(1) - go func() { + switch kd.Conf.Role { + case config.KubernetesRolePod, config.KubernetesRoleContainer: + pd := &podDiscovery{ + retryInterval: time.Duration(kd.Conf.RetryInterval), + kd: kd, + } pd.run(ctx, ch) - wg.Done() - }() - - nd := &nodeDiscovery{ - retryInterval: time.Duration(kd.Conf.RetryInterval), - kd: kd, - } - wg.Add(1) - go func() { + case config.KubernetesRoleNode: + nd := &nodeDiscovery{ + retryInterval: time.Duration(kd.Conf.RetryInterval), + kd: kd, + } nd.run(ctx, ch) - wg.Done() - }() - - sd := &serviceDiscovery{ - retryInterval: time.Duration(kd.Conf.RetryInterval), - kd: kd, - } - wg.Add(1) - go func() { + case config.KubernetesRoleService, config.KubernetesRoleEndpoint: + sd := &serviceDiscovery{ + retryInterval: time.Duration(kd.Conf.RetryInterval), + kd: kd, + } sd.run(ctx, ch) - wg.Done() - }() - - // Send an initial full view. - // TODO(fabxc): this does not include all available services and service - // endpoints yet. Service endpoints were also missing in the previous Sources() method. - var all []*config.TargetGroup - - all = append(all, kd.updateAPIServersTargetGroup()) - - select { - case ch <- all: - case <-ctx.Done(): + case config.KubernetesRoleAPIServer: + select { + case ch <- []*config.TargetGroup{kd.updateAPIServersTargetGroup()}: + case <-ctx.Done(): + return + } + default: + log.Errorf("unknown Kubernetes discovery kind %q", kd.Conf.Role) return } - - wg.Wait() } func (kd *Discovery) queryAPIServerPath(path string) (*http.Response, error) {