discovery/ec2: Support filtering instances in discovery (#4011)

This commit is contained in:
Kristiyan Nikolov 2018-03-31 09:51:11 +03:00 committed by Brian Brazil
parent 93494d8b7e
commit be85ba3842
5 changed files with 71 additions and 1 deletions

View file

@ -412,6 +412,16 @@ var expectedConf = &Config{
Profile: "profile",
RefreshInterval: model.Duration(60 * time.Second),
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",
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) {

View file

@ -182,6 +182,15 @@ scrape_configs:
access_key: access
secret_key: mysecret
profile: profile
filters:
- name: tag:environment
values:
- prod
- name: tag:service
values:
- web
- db
- job_name: service-azure
azure_sd_configs:

View file

@ -0,0 +1,9 @@
scrape_configs:
- job_name: prometheus
ec2_sd_configs:
- region: 'us-east-1'
filters:
- name: 'tag:environment'
values:

View file

@ -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.
type SDConfig struct {
Region string `yaml:"region"`
@ -79,6 +85,7 @@ type SDConfig struct {
RoleARN string `yaml:"role_arn,omitempty"`
RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"`
Port int `yaml:"port"`
Filters []*Filter `yaml:"filters"`
// Catches all undefined fields and must be empty after parsing.
XXX map[string]interface{} `yaml:",inline"`
@ -107,6 +114,11 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
}
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
}
@ -123,6 +135,7 @@ type Discovery struct {
profile string
roleARN string
port int
filters []*Filter
logger log.Logger
}
@ -142,6 +155,7 @@ func NewDiscovery(conf *SDConfig, logger log.Logger) *Discovery {
},
profile: conf.Profile,
roleARN: conf.RoleARN,
filters: conf.Filters,
interval: time.Duration(conf.RefreshInterval),
port: conf.Port,
logger: logger,
@ -212,7 +226,18 @@ func (d *Discovery) refresh() (tg *targetgroup.Group, err error) {
tg = &targetgroup.Group{
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 _, inst := range r.Instances {
if inst.PrivateIpAddress == nil {

View file

@ -429,8 +429,21 @@ region: <string>
# The port to scrape metrics from. If using the public IP address, this must
# instead be specified in the relabeling rule.
[ 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 configurations allow retrieving scrape targets from OpenStack Nova