mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
discovery/ec2: Support filtering instances in discovery (#4011)
This commit is contained in:
parent
93494d8b7e
commit
be85ba3842
|
@ -412,6 +412,16 @@ var expectedConf = &Config{
|
||||||
Profile: "profile",
|
Profile: "profile",
|
||||||
RefreshInterval: model.Duration(60 * time.Second),
|
RefreshInterval: model.Duration(60 * time.Second),
|
||||||
Port: 80,
|
Port: 80,
|
||||||
|
Filters: []*ec2.Filter{
|
||||||
|
{
|
||||||
|
Name: "tag:environment",
|
||||||
|
Values: []string{"prod"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "tag:service",
|
||||||
|
Values: []string{"web", "db"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -688,6 +698,10 @@ var expectedErrors = []struct {
|
||||||
filename: "remote_write_url_missing.bad.yml",
|
filename: "remote_write_url_missing.bad.yml",
|
||||||
errMsg: `url for remote_write is empty`,
|
errMsg: `url for remote_write is empty`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
filename: "ec2_filters_empty_values.bad.yml",
|
||||||
|
errMsg: `EC2 SD configuration filter values cannot be empty`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBadConfigs(t *testing.T) {
|
func TestBadConfigs(t *testing.T) {
|
||||||
|
|
9
config/testdata/conf.good.yml
vendored
9
config/testdata/conf.good.yml
vendored
|
@ -182,6 +182,15 @@ scrape_configs:
|
||||||
access_key: access
|
access_key: access
|
||||||
secret_key: mysecret
|
secret_key: mysecret
|
||||||
profile: profile
|
profile: profile
|
||||||
|
filters:
|
||||||
|
- name: tag:environment
|
||||||
|
values:
|
||||||
|
- prod
|
||||||
|
|
||||||
|
- name: tag:service
|
||||||
|
values:
|
||||||
|
- web
|
||||||
|
- db
|
||||||
|
|
||||||
- job_name: service-azure
|
- job_name: service-azure
|
||||||
azure_sd_configs:
|
azure_sd_configs:
|
||||||
|
|
9
config/testdata/ec2_filters_empty_values.bad.yml
vendored
Normal file
9
config/testdata/ec2_filters_empty_values.bad.yml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: prometheus
|
||||||
|
|
||||||
|
ec2_sd_configs:
|
||||||
|
- region: 'us-east-1'
|
||||||
|
filters:
|
||||||
|
- name: 'tag:environment'
|
||||||
|
values:
|
||||||
|
|
|
@ -70,6 +70,12 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Filter is the configuration for filtering EC2 instances.
|
||||||
|
type Filter struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Values []string `yaml:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
// SDConfig is the configuration for EC2 based service discovery.
|
// SDConfig is the configuration for EC2 based service discovery.
|
||||||
type SDConfig struct {
|
type SDConfig struct {
|
||||||
Region string `yaml:"region"`
|
Region string `yaml:"region"`
|
||||||
|
@ -79,6 +85,7 @@ type SDConfig struct {
|
||||||
RoleARN string `yaml:"role_arn,omitempty"`
|
RoleARN string `yaml:"role_arn,omitempty"`
|
||||||
RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"`
|
RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"`
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
|
Filters []*Filter `yaml:"filters"`
|
||||||
|
|
||||||
// Catches all undefined fields and must be empty after parsing.
|
// Catches all undefined fields and must be empty after parsing.
|
||||||
XXX map[string]interface{} `yaml:",inline"`
|
XXX map[string]interface{} `yaml:",inline"`
|
||||||
|
@ -107,6 +114,11 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
}
|
}
|
||||||
c.Region = region
|
c.Region = region
|
||||||
}
|
}
|
||||||
|
for _, f := range c.Filters {
|
||||||
|
if len(f.Values) == 0 {
|
||||||
|
return fmt.Errorf("EC2 SD configuration filter values cannot be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +135,7 @@ type Discovery struct {
|
||||||
profile string
|
profile string
|
||||||
roleARN string
|
roleARN string
|
||||||
port int
|
port int
|
||||||
|
filters []*Filter
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +155,7 @@ func NewDiscovery(conf *SDConfig, logger log.Logger) *Discovery {
|
||||||
},
|
},
|
||||||
profile: conf.Profile,
|
profile: conf.Profile,
|
||||||
roleARN: conf.RoleARN,
|
roleARN: conf.RoleARN,
|
||||||
|
filters: conf.Filters,
|
||||||
interval: time.Duration(conf.RefreshInterval),
|
interval: time.Duration(conf.RefreshInterval),
|
||||||
port: conf.Port,
|
port: conf.Port,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
@ -212,7 +226,18 @@ func (d *Discovery) refresh() (tg *targetgroup.Group, err error) {
|
||||||
tg = &targetgroup.Group{
|
tg = &targetgroup.Group{
|
||||||
Source: *d.aws.Region,
|
Source: *d.aws.Region,
|
||||||
}
|
}
|
||||||
if err = ec2s.DescribeInstancesPages(nil, func(p *ec2.DescribeInstancesOutput, lastPage bool) bool {
|
|
||||||
|
var filters []*ec2.Filter
|
||||||
|
for _, f := range d.filters {
|
||||||
|
filters = append(filters, &ec2.Filter{
|
||||||
|
Name: aws.String(f.Name),
|
||||||
|
Values: aws.StringSlice(f.Values),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
input := &ec2.DescribeInstancesInput{Filters: filters}
|
||||||
|
|
||||||
|
if err = ec2s.DescribeInstancesPages(input, func(p *ec2.DescribeInstancesOutput, lastPage bool) bool {
|
||||||
for _, r := range p.Reservations {
|
for _, r := range p.Reservations {
|
||||||
for _, inst := range r.Instances {
|
for _, inst := range r.Instances {
|
||||||
if inst.PrivateIpAddress == nil {
|
if inst.PrivateIpAddress == nil {
|
||||||
|
|
|
@ -429,8 +429,21 @@ region: <string>
|
||||||
# The port to scrape metrics from. If using the public IP address, this must
|
# The port to scrape metrics from. If using the public IP address, this must
|
||||||
# instead be specified in the relabeling rule.
|
# instead be specified in the relabeling rule.
|
||||||
[ port: <int> | default = 80 ]
|
[ port: <int> | default = 80 ]
|
||||||
|
|
||||||
|
# Filters can be used optionally to filter the instance list by other criteria.
|
||||||
|
# Available filter criteria can be found here:
|
||||||
|
# https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html
|
||||||
|
# Filter API documentation: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Filter.html
|
||||||
|
filters:
|
||||||
|
[ - name: <string>
|
||||||
|
values: <string>, [...] ]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The [relabeling phase](#relabel_config) is the preferred and more powerful
|
||||||
|
way to filter targets based on arbitrary labels. For users with thousands of
|
||||||
|
instances it can be more efficient to use the EC2 API directly which has
|
||||||
|
support for filtering instances.
|
||||||
|
|
||||||
### `<openstack_sd_config>`
|
### `<openstack_sd_config>`
|
||||||
|
|
||||||
OpenStack SD configurations allow retrieving scrape targets from OpenStack Nova
|
OpenStack SD configurations allow retrieving scrape targets from OpenStack Nova
|
||||||
|
|
Loading…
Reference in a new issue