diff --git a/config/config_test.go b/config/config_test.go index 73a747cc6d..aa3e0b6e82 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -621,6 +621,7 @@ var expectedConf = &Config{ Role: "instance", Region: "RegionOne", Port: 80, + Availability: "public", RefreshInterval: model.Duration(60 * time.Second), TLSConfig: config_util.TLSConfig{ CAFile: "testdata/valid_ca_file", @@ -846,6 +847,9 @@ var expectedErrors = []struct { }, { filename: "openstack_role.bad.yml", errMsg: "unknown OpenStack SD role", + }, { + filename: "openstack_availability.bad.yml", + errMsg: "unknown availability invalid, must be one of admin, internal or public", }, { filename: "url_in_targetgroup.bad.yml", errMsg: "\"http://bad\" is not a valid hostname", diff --git a/config/testdata/openstack_availability.bad.yml b/config/testdata/openstack_availability.bad.yml new file mode 100644 index 0000000000..0ed51b44cc --- /dev/null +++ b/config/testdata/openstack_availability.bad.yml @@ -0,0 +1,4 @@ +scrape_configs: +- openstack_sd_configs: + - availability: invalid + diff --git a/discovery/openstack/hypervisor.go b/discovery/openstack/hypervisor.go index 872992d8d2..81d0e10c99 100644 --- a/discovery/openstack/hypervisor.go +++ b/discovery/openstack/hypervisor.go @@ -40,18 +40,19 @@ const ( // HypervisorDiscovery discovers OpenStack hypervisors. type HypervisorDiscovery struct { - provider *gophercloud.ProviderClient - authOpts *gophercloud.AuthOptions - region string - logger log.Logger - port int + provider *gophercloud.ProviderClient + authOpts *gophercloud.AuthOptions + region string + logger log.Logger + port int + availability gophercloud.Availability } // newHypervisorDiscovery returns a new hypervisor discovery. func newHypervisorDiscovery(provider *gophercloud.ProviderClient, opts *gophercloud.AuthOptions, - port int, region string, l log.Logger) *HypervisorDiscovery { + port int, region string, availability gophercloud.Availability, l log.Logger) *HypervisorDiscovery { return &HypervisorDiscovery{provider: provider, authOpts: opts, - region: region, port: port, logger: l} + region: region, port: port, availability: availability, logger: l} } func (h *HypervisorDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { @@ -60,8 +61,9 @@ func (h *HypervisorDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group if err != nil { return nil, errors.Wrap(err, "could not authenticate to OpenStack") } + client, err := openstack.NewComputeV2(h.provider, gophercloud.EndpointOpts{ - Region: h.region, + Region: h.region, Availability: h.availability, }) if err != nil { return nil, errors.Wrap(err, "could not create OpenStack compute session") diff --git a/discovery/openstack/instance.go b/discovery/openstack/instance.go index f3badb86c0..8ae4a05b70 100644 --- a/discovery/openstack/instance.go +++ b/discovery/openstack/instance.go @@ -47,22 +47,23 @@ const ( // InstanceDiscovery discovers OpenStack instances. type InstanceDiscovery struct { - provider *gophercloud.ProviderClient - authOpts *gophercloud.AuthOptions - region string - logger log.Logger - port int - allTenants bool + provider *gophercloud.ProviderClient + authOpts *gophercloud.AuthOptions + region string + logger log.Logger + port int + allTenants bool + availability gophercloud.Availability } // NewInstanceDiscovery returns a new instance discovery. func newInstanceDiscovery(provider *gophercloud.ProviderClient, opts *gophercloud.AuthOptions, - port int, region string, allTenants bool, l log.Logger) *InstanceDiscovery { + port int, region string, allTenants bool, availability gophercloud.Availability, l log.Logger) *InstanceDiscovery { if l == nil { l = log.NewNopLogger() } return &InstanceDiscovery{provider: provider, authOpts: opts, - region: region, port: port, allTenants: allTenants, logger: l} + region: region, port: port, allTenants: allTenants, availability: availability, logger: l} } type floatingIPKey struct { @@ -76,8 +77,9 @@ func (i *InstanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, if err != nil { return nil, errors.Wrap(err, "could not authenticate to OpenStack") } + client, err := openstack.NewComputeV2(i.provider, gophercloud.EndpointOpts{ - Region: i.region, + Region: i.region, Availability: i.availability, }) if err != nil { return nil, errors.Wrap(err, "could not create OpenStack compute session") diff --git a/discovery/openstack/openstack.go b/discovery/openstack/openstack.go index 65f8c6c43a..6f35566e60 100644 --- a/discovery/openstack/openstack.go +++ b/discovery/openstack/openstack.go @@ -15,6 +15,7 @@ package openstack import ( "context" + "fmt" "net/http" "time" @@ -34,6 +35,7 @@ import ( var DefaultSDConfig = SDConfig{ Port: 80, RefreshInterval: model.Duration(60 * time.Second), + Availability: "public", } // SDConfig is the configuration for OpenStack based service discovery. @@ -55,6 +57,7 @@ type SDConfig struct { Port int `yaml:"port"` AllTenants bool `yaml:"all_tenants,omitempty"` TLSConfig config_util.TLSConfig `yaml:"tls_config,omitempty"` + Availability string `yaml:"availability,omitempty"` } // Role is the role of the target in OpenStack. @@ -91,12 +94,20 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { if err != nil { return err } + + switch c.Availability { + case "public", "internal", "admin": + default: + return fmt.Errorf("unknown availability %s, must be one of admin, internal or public", c.Availability) + } + if c.Role == "" { return errors.New("role missing (one of: instance, hypervisor)") } if c.Region == "" { return errors.New("openstack SD configuration requires a region") } + return nil } @@ -161,11 +172,12 @@ func newRefresher(conf *SDConfig, l log.Logger) (refresher, error) { }, Timeout: 5 * time.Duration(conf.RefreshInterval), } + availability := gophercloud.Availability(conf.Availability) switch conf.Role { case OpenStackRoleHypervisor: - return newHypervisorDiscovery(client, &opts, conf.Port, conf.Region, l), nil + return newHypervisorDiscovery(client, &opts, conf.Port, conf.Region, availability, l), nil case OpenStackRoleInstance: - return newInstanceDiscovery(client, &opts, conf.Port, conf.Region, conf.AllTenants, l), nil + return newInstanceDiscovery(client, &opts, conf.Port, conf.Region, conf.AllTenants, availability, l), nil } return nil, errors.New("unknown OpenStack discovery role") } diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index 7c289931d9..467714c1e2 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -773,6 +773,9 @@ region: # instead be specified in the relabeling rule. [ port: | default = 80 ] +# The availability of the endpoint to connect to. Must be one of public, admin or internal. +[ availability: | default = "public" ] + # TLS configuration. tls_config: [ ]