Skip to content

Commit cf5fafb

Browse files
authored
Add openstack ssl provider in add_cloud_metadata (#21590)
Add a new provider to query metadata from OpenStack deployments using HTTPS. Add the usual SSL settings available in other features that support TLS.
1 parent 048a404 commit cf5fafb

File tree

8 files changed

+87
-27
lines changed

8 files changed

+87
-27
lines changed

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
453453
- Cloud Foundry metadata is cached to disk. {pull}20775[20775]
454454
- Add option to select the type of index template to load: legacy, component, index. {pull}21212[21212]
455455
- Release `add_cloudfoundry_metadata` as GA. {pull}21525[21525]
456+
- Add support for OpenStack SSL metadata APIs in `add_cloud_metadata`. {pull}21590[21590]
456457

457458
*Auditbeat*
458459

libbeat/processors/add_cloud_metadata/add_cloud_metadata.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"github.com/elastic/beats/v7/libbeat/beat"
2828
"github.com/elastic/beats/v7/libbeat/common"
29+
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
2930
"github.com/elastic/beats/v7/libbeat/logp"
3031
"github.com/elastic/beats/v7/libbeat/processors"
3132
jsprocessor "github.com/elastic/beats/v7/libbeat/processors/script/javascript/module/processor"
@@ -53,6 +54,7 @@ type addCloudMetadata struct {
5354
type initData struct {
5455
fetchers []metadataFetcher
5556
timeout time.Duration
57+
tlsConfig *tlscommon.TLSConfig
5658
overwrite bool
5759
}
5860

@@ -63,14 +65,24 @@ func New(c *common.Config) (processors.Processor, error) {
6365
return nil, errors.Wrap(err, "failed to unpack add_cloud_metadata config")
6466
}
6567

68+
tlsConfig, err := tlscommon.LoadTLSConfig(config.TLS)
69+
if err != nil {
70+
return nil, errors.Wrap(err, "TLS configuration load")
71+
}
72+
6673
initProviders := selectProviders(config.Providers, cloudMetaProviders)
6774
fetchers, err := setupFetchers(initProviders, c)
6875
if err != nil {
6976
return nil, err
7077
}
7178
p := &addCloudMetadata{
72-
initData: &initData{fetchers, config.Timeout, config.Overwrite},
73-
logger: logp.NewLogger("add_cloud_metadata"),
79+
initData: &initData{
80+
fetchers: fetchers,
81+
timeout: config.Timeout,
82+
tlsConfig: tlsConfig,
83+
overwrite: config.Overwrite,
84+
},
85+
logger: logp.NewLogger("add_cloud_metadata"),
7486
}
7587

7688
go p.init()

libbeat/processors/add_cloud_metadata/config.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ package add_cloud_metadata
2020
import (
2121
"fmt"
2222
"time"
23+
24+
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
2325
)
2426

2527
type config struct {
26-
Timeout time.Duration `config:"timeout"` // Amount of time to wait for responses from the metadata services.
27-
Overwrite bool `config:"overwrite"` // Overwrite if cloud.* fields already exist.
28-
Providers providerList `config:"providers"` // List of providers to probe
28+
Timeout time.Duration `config:"timeout"` // Amount of time to wait for responses from the metadata services.
29+
TLS *tlscommon.Config `config:"ssl"` // TLS configuration
30+
Overwrite bool `config:"overwrite"` // Overwrite if cloud.* fields already exist.
31+
Providers providerList `config:"providers"` // List of providers to probe
2932
}
3033

3134
type providerList []string

libbeat/processors/add_cloud_metadata/docs/add_cloud_metadata.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,16 @@ List of names the `providers` setting supports:
5252
- "aws", or "ec2" for Amazon Web Services (enabled by default).
5353
- "gcp" for Google Copmute Enging (enabled by default).
5454
- "openstack", or "nova" for Openstack Nova (enabled by default).
55+
- "openstack-ssl", or "nova-ssl" for Openstack Nova when SSL metadata APIs are enabled (enabled by default).
5556
- "tencent", or "qcloud" for Tencent Cloud (disabled by default).
5657

5758
The third optional configuration setting is `overwrite`. When `overwrite` is
5859
`true`, `add_cloud_metadata` overwrites existing `cloud.*` fields (`false` by
5960
default).
6061

62+
The `add_cloud_metadata` processor supports SSL options to configure the http
63+
client used to query cloud metadata. See <<configuration-ssl>> for more information.
64+
6165
The metadata that is added to events varies by hosting provider. Below are
6266
examples for each of the supported providers.
6367

libbeat/processors/add_cloud_metadata/http_fetcher.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/pkg/errors"
2828

2929
"github.com/elastic/beats/v7/libbeat/common"
30+
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
3031
)
3132

3233
type httpMetadataFetcher struct {
@@ -127,9 +128,15 @@ func (f *httpMetadataFetcher) fetchRaw(
127128

128129
// getMetadataURLs loads config and generates the metadata URLs.
129130
func getMetadataURLs(c *common.Config, defaultHost string, metadataURIs []string) ([]string, error) {
131+
return getMetadataURLsWithScheme(c, "http", defaultHost, metadataURIs)
132+
}
133+
134+
// getMetadataURLsWithScheme loads config and generates the metadata URLs.
135+
func getMetadataURLsWithScheme(c *common.Config, scheme string, defaultHost string, metadataURIs []string) ([]string, error) {
130136
var urls []string
131137
config := struct {
132-
MetadataHostAndPort string `config:"host"` // Specifies the host and port of the metadata service (for testing purposes only).
138+
MetadataHostAndPort string `config:"host"` // Specifies the host and port of the metadata service (for testing purposes only).
139+
TLSConfig *tlscommon.Config `config:"ssl"`
133140
}{
134141
MetadataHostAndPort: defaultHost,
135142
}
@@ -138,7 +145,7 @@ func getMetadataURLs(c *common.Config, defaultHost string, metadataURIs []string
138145
return urls, errors.Wrap(err, "failed to unpack add_cloud_metadata config")
139146
}
140147
for _, uri := range metadataURIs {
141-
urls = append(urls, "http://"+config.MetadataHostAndPort+uri)
148+
urls = append(urls, scheme+"://"+config.MetadataHostAndPort+uri)
142149
}
143150
return urls, nil
144151
}

libbeat/processors/add_cloud_metadata/provider_openstack_nova.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,24 @@ const (
3232
// OpenStack Nova Metadata Service
3333
// Document https://docs.openstack.org/nova/latest/user/metadata-service.html
3434
var openstackNovaMetadataFetcher = provider{
35-
Name: "openstack-nova",
35+
Name: "openstack-nova",
36+
Local: true,
37+
Create: buildOpenstackNovaCreate("http"),
38+
}
3639

37-
Local: true,
40+
var openstackNovaSSLMetadataFetcher = provider{
41+
Name: "openstack-nova-ssl",
42+
Local: true,
43+
Create: buildOpenstackNovaCreate("https"),
44+
}
3845

39-
Create: func(provider string, c *common.Config) (metadataFetcher, error) {
46+
func buildOpenstackNovaCreate(scheme string) func(provider string, c *common.Config) (metadataFetcher, error) {
47+
return func(provider string, c *common.Config) (metadataFetcher, error) {
4048
osSchema := func(m map[string]interface{}) common.MapStr {
4149
return common.MapStr(m)
4250
}
4351

44-
urls, err := getMetadataURLs(c, metadataHost, []string{
52+
urls, err := getMetadataURLsWithScheme(c, scheme, metadataHost, []string{
4553
osMetadataInstanceIDURI,
4654
osMetadataInstanceTypeURI,
4755
osMetadataHostnameURI,
@@ -71,5 +79,5 @@ var openstackNovaMetadataFetcher = provider{
7179
}
7280
fetcher := &httpMetadataFetcher{"openstack", nil, responseHandlers, osSchema}
7381
return fetcher, nil
74-
},
82+
}
7583
}

libbeat/processors/add_cloud_metadata/provider_openstack_nova_test.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import (
2929
"github.com/elastic/beats/v7/libbeat/logp"
3030
)
3131

32-
func initOpenstackNovaTestServer() *httptest.Server {
33-
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
32+
func openstackNovaMetadataHandler() http.HandlerFunc {
33+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3434
if r.RequestURI == osMetadataInstanceIDURI {
3535
w.Write([]byte("i-0000ffac"))
3636
return
@@ -49,13 +49,13 @@ func initOpenstackNovaTestServer() *httptest.Server {
4949
}
5050

5151
http.Error(w, "not found", http.StatusNotFound)
52-
}))
52+
})
5353
}
5454

5555
func TestRetrieveOpenstackNovaMetadata(t *testing.T) {
5656
logp.TestingSetup()
5757

58-
server := initOpenstackNovaTestServer()
58+
server := httptest.NewServer(openstackNovaMetadataHandler())
5959
defer server.Close()
6060

6161
config, err := common.NewConfigFrom(map[string]interface{}{
@@ -66,6 +66,28 @@ func TestRetrieveOpenstackNovaMetadata(t *testing.T) {
6666
t.Fatal(err)
6767
}
6868

69+
assertOpenstackNova(t, config)
70+
}
71+
72+
func TestRetrieveOpenstackNovaMetadataWithHTTPS(t *testing.T) {
73+
logp.TestingSetup()
74+
75+
server := httptest.NewTLSServer(openstackNovaMetadataHandler())
76+
defer server.Close()
77+
78+
config, err := common.NewConfigFrom(map[string]interface{}{
79+
"host": server.Listener.Addr().String(),
80+
"ssl.verification_mode": "none",
81+
})
82+
83+
if err != nil {
84+
t.Fatal(err)
85+
}
86+
87+
assertOpenstackNova(t, config)
88+
}
89+
90+
func assertOpenstackNova(t *testing.T, config *common.Config) {
6991
p, err := New(config)
7092
if err != nil {
7193
t.Fatal(err)

libbeat/processors/add_cloud_metadata/providers.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,19 @@ type result struct {
5151
}
5252

5353
var cloudMetaProviders = map[string]provider{
54-
"alibaba": alibabaCloudMetadataFetcher,
55-
"ecs": alibabaCloudMetadataFetcher,
56-
"azure": azureVMMetadataFetcher,
57-
"digitalocean": doMetadataFetcher,
58-
"aws": ec2MetadataFetcher,
59-
"ec2": ec2MetadataFetcher,
60-
"gcp": gceMetadataFetcher,
61-
"openstack": openstackNovaMetadataFetcher,
62-
"nova": openstackNovaMetadataFetcher,
63-
"qcloud": qcloudMetadataFetcher,
64-
"tencent": qcloudMetadataFetcher,
54+
"alibaba": alibabaCloudMetadataFetcher,
55+
"ecs": alibabaCloudMetadataFetcher,
56+
"azure": azureVMMetadataFetcher,
57+
"digitalocean": doMetadataFetcher,
58+
"aws": ec2MetadataFetcher,
59+
"ec2": ec2MetadataFetcher,
60+
"gcp": gceMetadataFetcher,
61+
"openstack": openstackNovaMetadataFetcher,
62+
"nova": openstackNovaMetadataFetcher,
63+
"openstack-ssl": openstackNovaSSLMetadataFetcher,
64+
"nova-ssl": openstackNovaSSLMetadataFetcher,
65+
"qcloud": qcloudMetadataFetcher,
66+
"tencent": qcloudMetadataFetcher,
6567
}
6668

6769
func selectProviders(configList providerList, providers map[string]provider) map[string]provider {
@@ -138,6 +140,7 @@ func (p *addCloudMetadata) fetchMetadata() *result {
138140
Timeout: p.initData.timeout,
139141
KeepAlive: 0,
140142
}).DialContext,
143+
TLSClientConfig: p.initData.tlsConfig.ToConfig(),
141144
},
142145
}
143146

0 commit comments

Comments
 (0)