From 7221228843bf0c969cd7357115adcebe24860219 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Fri, 1 Jul 2016 19:28:29 +0200 Subject: [PATCH] discovery/kubernetes: select between discovery role This adds `role` field to the Kubernetes SD config, which indicates which type of Kubernetes SD should be run. This no longer allows discovering pods and nodes with the same SD configuration for example. --- config/config.go | 28 +++++++- config/config_test.go | 1 + config/testdata/conf.good.yml | 3 +- .../testdata/kubernetes_bearertoken.bad.yml | 3 +- .../kubernetes_bearertoken_basicauth.bad.yml | 3 +- retrieval/discovery/kubernetes/discovery.go | 65 +++++++------------ 6 files changed, 58 insertions(+), 45 deletions(-) diff --git a/config/config.go b/config/config.go index 36847d045..079d546a6 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 a7555d878..ca9ab86a7 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 b911db767..ea9acfbf1 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 756644be6..533742fd3 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 9ef16ae4b..e7c1633d5 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 1e2a6698b..d06411d67 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) {