Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick #18096 to 7.x: Add k8s keystore backend #18774

Merged
merged 2 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Add `urldecode` processor to for decoding URL-encoded fields. {pull}17505[17505]
- Add support for AWS IAM `role_arn` in credentials config. {pull}17658[17658] {issue}12464[12464]
- Add Kerberos support to Elasticsearch output. {pull}17927[17927]
- Add k8s keystore backend. {pull}18096[18096]
- Set `agent.name` to the hostname by default. {issue}16377[16377] {pull}18000[18000]
- Add keystore support for autodiscover static configurations. {pull]16306[16306]
- Add support for basic ECS logging. {pull}17974[17974]
Expand Down
1 change: 1 addition & 0 deletions deploy/kubernetes/metricbeat-kubernetes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ rules:
- namespaces
- events
- pods
- secrets
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions"]
resources:
Expand Down
1 change: 1 addition & 0 deletions deploy/kubernetes/metricbeat/metricbeat-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ rules:
- namespaces
- events
- pods
- secrets
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions"]
resources:
Expand Down
8 changes: 5 additions & 3 deletions filebeat/autodiscover/builder/hints/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"fmt"
"regexp"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/filebeat/fileset"
"github.com/elastic/beats/v7/filebeat/harvester"
"github.com/elastic/beats/v7/libbeat/autodiscover"
Expand Down Expand Up @@ -70,7 +72,7 @@ func NewLogHints(cfg *common.Config) (autodiscover.Builder, error) {
}

// Create config based on input hints in the bus event
func (l *logHints) CreateConfig(event bus.Event) []*common.Config {
func (l *logHints) CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config {
var hints common.MapStr
hIface, ok := event["hints"]
if ok {
Expand Down Expand Up @@ -109,7 +111,7 @@ func (l *logHints) CreateConfig(event bus.Event) []*common.Config {
}
logp.Debug("hints.builder", "generated config %+v", configs)
// Apply information in event to the template to generate the final config
return template.ApplyConfigTemplate(event, configs, false)
return template.ApplyConfigTemplate(event, configs)
}

tempCfg := common.MapStr{}
Expand Down Expand Up @@ -163,7 +165,7 @@ func (l *logHints) CreateConfig(event bus.Event) []*common.Config {
logp.Debug("hints.builder", "generated config %+v", config)

// Apply information in event to the template to generate the final config
return template.ApplyConfigTemplate(event, []*common.Config{config}, false)
return template.ApplyConfigTemplate(event, []*common.Config{config})
}

func (l *logHints) getMultiline(hints common.MapStr) common.MapStr {
Expand Down
8 changes: 5 additions & 3 deletions heartbeat/autodiscover/builder/hints/monitors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strconv"
"strings"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/libbeat/autodiscover"
"github.com/elastic/beats/v7/libbeat/autodiscover/builder"
"github.com/elastic/beats/v7/libbeat/autodiscover/template"
Expand Down Expand Up @@ -60,7 +62,7 @@ func NewHeartbeatHints(cfg *common.Config) (autodiscover.Builder, error) {
}

// Create config based on input hints in the bus event
func (hb *heartbeatHints) CreateConfig(event bus.Event) []*common.Config {
func (hb *heartbeatHints) CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config {
var hints common.MapStr
hIface, ok := event["hints"]
if ok {
Expand Down Expand Up @@ -91,7 +93,7 @@ func (hb *heartbeatHints) CreateConfig(event bus.Event) []*common.Config {
}
hb.logger.Debugf("generated config %+v", configs)
// Apply information in event to the template to generate the final config
return template.ApplyConfigTemplate(event, configs, false)
return template.ApplyConfigTemplate(event, configs)
}

tempCfg := common.MapStr{}
Expand Down Expand Up @@ -121,7 +123,7 @@ func (hb *heartbeatHints) CreateConfig(event bus.Event) []*common.Config {
}

// Apply information in event to the template to generate the final config
return template.ApplyConfigTemplate(event, configs, false)
return template.ApplyConfigTemplate(event, configs)
}

func (hb *heartbeatHints) getType(hints common.MapStr) common.MapStr {
Expand Down
2 changes: 1 addition & 1 deletion libbeat/autodiscover/appenders/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (c *configAppender) Append(event bus.Event) {
}

// Apply the template
template.ApplyConfigTemplate(event, cfgs, false)
template.ApplyConfigTemplate(event, cfgs)
}

// Replace old config with newly appended configs
Expand Down
1 change: 0 additions & 1 deletion libbeat/autodiscover/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ func (a *Autodiscover) handleStart(event bus.Event) bool {
}

if a.logger.IsDebug() {

for _, c := range configs {
a.logger.Debugf("Generated config: %+v", common.DebugString(c, true))
}
Expand Down
44 changes: 32 additions & 12 deletions libbeat/autodiscover/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,25 @@ import (
"fmt"
"strings"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/bus"
"github.com/elastic/beats/v7/libbeat/keystore"
)

// Builder provides an interface by which configs can be built from provider metadata
type Builder interface {
// CreateConfig creates a config from hints passed from providers
CreateConfig(event bus.Event) []*common.Config
CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config
}

// Builders is a list of Builder objects
type Builders []Builder
// builders is a struct of Builder list objects and a `keystoreProvider`, which
// has access to a keystores registry
type Builders struct {
builders []Builder
keystoreProvider keystore.Provider
}

// BuilderConstructor is a func used to generate a Builder object
type BuilderConstructor func(*common.Config) (Builder, error)
Expand Down Expand Up @@ -89,9 +96,18 @@ func (r *registry) BuildBuilder(c *common.Config) (Builder, error) {
// GetConfig creates configs for all builders initialized.
func (b Builders) GetConfig(event bus.Event) []*common.Config {
configs := []*common.Config{}

for _, builder := range b {
if config := builder.CreateConfig(event); config != nil {
var opts []ucfg.Option

if b.keystoreProvider != nil {
k8sKeystore := b.keystoreProvider.GetKeystore(event)
if k8sKeystore != nil {
opts = []ucfg.Option{
ucfg.Resolve(keystore.ResolverWrap(k8sKeystore)),
}
}
}
for _, builder := range b.builders {
if config := builder.CreateConfig(event, opts...); config != nil {
configs = append(configs, config...)
}
}
Expand All @@ -100,12 +116,16 @@ func (b Builders) GetConfig(event bus.Event) []*common.Config {
}

// NewBuilders instances the given list of builders. hintsCfg holds `hints` settings
// for simplified mode (single 'hints' builder)
func NewBuilders(bConfigs []*common.Config, hintsCfg *common.Config) (Builders, error) {
// for simplified mode (single 'hints' builder), `keystoreProvider` has access to keystore registry
func NewBuilders(
bConfigs []*common.Config,
hintsCfg *common.Config,
keystoreProvider keystore.Provider,
) (Builders, error) {
var builders Builders
if hintsCfg.Enabled() {
if len(bConfigs) > 0 {
return nil, errors.New("hints.enabled is incompatible with manually defining builders")
return Builders{}, errors.New("hints.enabled is incompatible with manually defining builders")
}

// pass rest of hints settings to the builder
Expand All @@ -116,10 +136,10 @@ func NewBuilders(bConfigs []*common.Config, hintsCfg *common.Config) (Builders,
for _, bcfg := range bConfigs {
builder, err := Registry.BuildBuilder(bcfg)
if err != nil {
return nil, err
return Builders{}, err
}
builders = append(builders, builder)
builders.builders = append(builders.builders, builder)
}

builders.keystoreProvider = keystoreProvider
return builders, nil
}
6 changes: 4 additions & 2 deletions libbeat/autodiscover/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import (

"github.com/stretchr/testify/assert"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/bus"
)

type fakeBuilder struct{}

func (f *fakeBuilder) CreateConfig(event bus.Event) []*common.Config {
func (f *fakeBuilder) CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config {
return []*common.Config{common.NewConfig()}
}

Expand Down Expand Up @@ -65,7 +67,7 @@ func TestBuilderRegistry(t *testing.T) {
assert.Equal(t, len(res), 1)

builders := Builders{}
builders = append(builders, builder)
builders.builders = append(builders.builders, builder)

// Try using builders object for the same as above and expect
// the same result
Expand Down
10 changes: 3 additions & 7 deletions libbeat/autodiscover/providers/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ type Provider struct {
stoppers map[string]*time.Timer
stopTrigger chan *dockerContainerMetadata
logger *logp.Logger
keystore keystore.Keystore
}

// AutodiscoverBuilder builds and returns an autodiscover provider
Expand All @@ -78,15 +77,15 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
return nil, errWrap(err)
}

mapper, err := template.NewConfigMapper(config.Templates)
mapper, err := template.NewConfigMapper(config.Templates, keystore, nil)
if err != nil {
return nil, errWrap(err)
}
if len(mapper) == 0 && !config.Hints.Enabled() {
if len(mapper.ConditionMaps) == 0 && !config.Hints.Enabled() {
return nil, errWrap(fmt.Errorf("no configs or hints defined for autodiscover provider"))
}

builders, err := autodiscover.NewBuilders(config.Builders, config.Hints)
builders, err := autodiscover.NewBuilders(config.Builders, config.Hints, nil)
if err != nil {
return nil, errWrap(err)
}
Expand Down Expand Up @@ -117,7 +116,6 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
stoppers: make(map[string]*time.Timer),
stopTrigger: make(chan *dockerContainerMetadata),
logger: logger,
keystore: keystore,
}, nil
}

Expand Down Expand Up @@ -306,8 +304,6 @@ func (d *Provider) emitContainer(container *docker.Container, meta *dockerMetada
}

func (d *Provider) publish(event bus.Event) {
// attach keystore to the event to be consumed by the static configs
event["keystore"] = d.keystore
// Try to match a config
if config := d.templates.GetConfig(event); config != nil {
event["config"] = config
Expand Down
10 changes: 3 additions & 7 deletions libbeat/autodiscover/providers/jolokia/jolokia.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ type Provider struct {
appenders autodiscover.Appenders
templates template.Mapper
discovery DiscoveryProber
keystore keystore.Keystore
}

// AutodiscoverBuilder builds a Jolokia Discovery autodiscover provider, it fails if
Expand All @@ -70,15 +69,15 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
Interfaces: config.Interfaces,
}

mapper, err := template.NewConfigMapper(config.Templates)
mapper, err := template.NewConfigMapper(config.Templates, keystore, nil)
if err != nil {
return nil, errWrap(err)
}
if len(mapper) == 0 {
if len(mapper.ConditionMaps) == 0 {
return nil, errWrap(fmt.Errorf("no configs defined for autodiscover provider"))
}

builders, err := autodiscover.NewBuilders(config.Builders, nil)
builders, err := autodiscover.NewBuilders(config.Builders, nil, nil)
Copy link
Member

@jsoriano jsoriano May 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should start thinking in a different way of setting optional features in these autodiscover builders (and config mappers above).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, that would make sense!

if err != nil {
return nil, errWrap(err)
}
Expand All @@ -94,7 +93,6 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
builders: builders,
appenders: appenders,
discovery: discovery,
keystore: keystore,
}, nil
}

Expand All @@ -109,8 +107,6 @@ func (p *Provider) Start() {
}

func (p *Provider) publish(event bus.Event) {
// attach keystore to the event to be consumed by the static configs
event["keystore"] = p.keystore
if config := p.templates.GetConfig(event); config != nil {
event["config"] = config
} else if config := p.builders.GetConfig(event); config != nil {
Expand Down
4 changes: 3 additions & 1 deletion libbeat/autodiscover/providers/kubernetes/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/stretchr/testify/assert"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/libbeat/autodiscover"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/bus"
Expand Down Expand Up @@ -76,6 +78,6 @@ func newMockBuilder(_ *common.Config) (autodiscover.Builder, error) {
return &mockBuilder{}, nil
}

func (m *mockBuilder) CreateConfig(event bus.Event) []*common.Config {
func (m *mockBuilder) CreateConfig(event bus.Event, options ...ucfg.Option) []*common.Config {
return nil
}
11 changes: 5 additions & 6 deletions libbeat/autodiscover/providers/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/bus"
"github.com/elastic/beats/v7/libbeat/common/kubernetes"
"github.com/elastic/beats/v7/libbeat/common/kubernetes/k8skeystore"
"github.com/elastic/beats/v7/libbeat/keystore"
"github.com/elastic/beats/v7/libbeat/logp"
)
Expand All @@ -55,7 +56,6 @@ type Provider struct {
appenders autodiscover.Appenders
logger *logp.Logger
eventer Eventer
keystore keystore.Keystore
}

// AutodiscoverBuilder builds and returns an autodiscover provider
Expand All @@ -77,12 +77,14 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
return nil, errWrap(err)
}

mapper, err := template.NewConfigMapper(config.Templates)
k8sKeystoreProvider := k8skeystore.NewKubernetesKeystoresRegistry(logger, client)

mapper, err := template.NewConfigMapper(config.Templates, keystore, k8sKeystoreProvider)
if err != nil {
return nil, errWrap(err)
}

builders, err := autodiscover.NewBuilders(config.Builders, config.Hints)
builders, err := autodiscover.NewBuilders(config.Builders, config.Hints, k8sKeystoreProvider)
if err != nil {
return nil, errWrap(err)
}
Expand All @@ -99,7 +101,6 @@ func AutodiscoverBuilder(bus bus.Bus, uuid uuid.UUID, c *common.Config, keystore
builders: builders,
appenders: appenders,
logger: logger,
keystore: keystore,
}

switch config.Resource {
Expand Down Expand Up @@ -138,8 +139,6 @@ func (p *Provider) String() string {
}

func (p *Provider) publish(event bus.Event) {
// attach keystore to the event to be consumed by the static configs
event["keystore"] = p.keystore
// Try to match a config
if config := p.templates.GetConfig(event); config != nil {
event["config"] = config
Expand Down
Loading