lib/promscrape/discovery/dockerswarm: fix discovery filters being applied to all objects (#3632)

* lib/promscrape/discovery/dockerswarm: fix discovery filters being applied to all objects

Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>

* Update docs/CHANGELOG.md

Signed-off-by: Zakhar Bessarab <z.bessarab@victoriametrics.com>
Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Zakhar Bessarab 2023-01-12 10:50:34 +04:00 committed by Aliaksandr Valialkin
parent 4295ca2ce2
commit ae5b85966a
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
7 changed files with 36 additions and 9 deletions

View file

@ -15,6 +15,8 @@ The following tip changes can be tested by building VictoriaMetrics components f
## tip
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs): apply `filters` only to objects of the specified `role`. Previously filters were applied to all the objects, which could cause errors when different types of objects were used with filters that were not compatible with them. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3579).
## [v1.86.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.86.1)

View file

@ -16,6 +16,9 @@ type apiConfig struct {
client *discoveryutils.Client
port int
// role is the type of objects to discover.
role string
// filtersQueryArg contains escaped `filters` query arg to add to each request to Docker Swarm API.
filtersQueryArg string
}
@ -49,11 +52,12 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err)
}
cfg.client = client
cfg.role = sdc.Role
return cfg, nil
}
func (cfg *apiConfig) getAPIResponse(path string) ([]byte, error) {
if len(cfg.filtersQueryArg) > 0 {
func (cfg *apiConfig) getAPIResponse(path, filtersQueryArg string) ([]byte, error) {
if len(filtersQueryArg) > 0 {
separator := "?"
if strings.Contains(path, "?") {
separator = "&"

View file

@ -15,6 +15,12 @@ var SDCheckInterval = flag.Duration("promscrape.dockerswarmSDCheckInterval", 30*
"This works only if dockerswarm_sd_configs is configured in '-promscrape.config' file. "+
"See https://docs.victoriametrics.com/sd_configs.html#dockerswarm_sd_configs for details")
const (
roleTasks = "tasks"
roleServices = "services"
roleNodes = "nodes"
)
// SDConfig represents docker swarm service discovery configuration
//
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config
@ -43,11 +49,11 @@ func (sdc *SDConfig) GetLabels(baseDir string) ([]*promutils.Labels, error) {
return nil, fmt.Errorf("cannot get API config: %w", err)
}
switch sdc.Role {
case "tasks":
case roleTasks:
return getTasksLabels(cfg)
case "services":
case roleServices:
return getServicesLabels(cfg)
case "nodes":
case roleNodes:
return getNodesLabels(cfg)
default:
return nil, fmt.Errorf("unexpected `role`: %q; must be one of `tasks`, `services` or `nodes`; skipping it", sdc.Role)

View file

@ -28,7 +28,7 @@ func getNetworksLabelsByNetworkID(cfg *apiConfig) (map[string]*promutils.Labels,
}
func getNetworks(cfg *apiConfig) ([]network, error) {
resp, err := cfg.getAPIResponse("/networks")
resp, err := cfg.getAPIResponse("/networks", "")
if err != nil {
return nil, fmt.Errorf("cannot query dockerswarm api for networks: %w", err)
}

View file

@ -47,7 +47,12 @@ func getNodesLabels(cfg *apiConfig) ([]*promutils.Labels, error) {
}
func getNodes(cfg *apiConfig) ([]node, error) {
resp, err := cfg.getAPIResponse("/nodes")
filtersQueryArg := ""
if cfg.role == roleNodes {
filtersQueryArg = cfg.filtersQueryArg
}
resp, err := cfg.getAPIResponse("/nodes", filtersQueryArg)
if err != nil {
return nil, fmt.Errorf("cannot query dockerswarm api for nodes: %w", err)
}

View file

@ -59,7 +59,12 @@ func getServicesLabels(cfg *apiConfig) ([]*promutils.Labels, error) {
}
func getServices(cfg *apiConfig) ([]service, error) {
data, err := cfg.getAPIResponse("/services")
filtersQueryArg := ""
if cfg.role == roleServices {
filtersQueryArg = cfg.filtersQueryArg
}
data, err := cfg.getAPIResponse("/services", filtersQueryArg)
if err != nil {
return nil, fmt.Errorf("cannot query dockerswarm api for services: %w", err)
}

View file

@ -62,7 +62,12 @@ func getTasksLabels(cfg *apiConfig) ([]*promutils.Labels, error) {
}
func getTasks(cfg *apiConfig) ([]task, error) {
resp, err := cfg.getAPIResponse("/tasks")
filtersQueryArg := ""
if cfg.role == roleTasks {
filtersQueryArg = cfg.filtersQueryArg
}
resp, err := cfg.getAPIResponse("/tasks", filtersQueryArg)
if err != nil {
return nil, fmt.Errorf("cannot query dockerswarm api for tasks: %w", err)
}