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

Add Central Management blacklisting #9099

Merged
merged 8 commits into from
Dec 12, 2018
Merged

Conversation

exekias
Copy link
Contributor

@exekias exekias commented Nov 15, 2018

This change allows to define local blacklist for configurations coming
from Central Management. If a configuration block matches the given
regular expession, it will be ignored:

For example:

management:
  blacklist:
    output: console
    metricbeat.modules.module: k.{18}s

This change allows to define local blacklist for configurations coming
from Central Management. If a configuration block matches the given
regular expession, it will be ignored:

For example:

```
management:
  blacklist:
    output: console
    metricbeat.modules.module: k.{18}s
```
@exekias exekias added enhancement review libbeat needs_backport PR is waiting to be backported to other branches. labels Nov 15, 2018
@exekias exekias requested review from ph and urso November 15, 2018 13:56
return fmt.Errorf("wrong type, expect map")
}

var expand func(key string, value interface{})
Copy link
Contributor

Choose a reason for hiding this comment

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

Not really needed since you are defining it below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's needed because this function is recursive, so internal calls need the definition beforehand

return result
}

func (c *ConfigBlacklist) blacklisted(blockType string, block *api.ConfigBlock) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe rename to isBlacklisted() because its a predicate?

}

return result
}
Copy link
Contributor

@ph ph Nov 15, 2018

Choose a reason for hiding this comment

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

From what I see, lets say that we receive a config block with a black listed option, we would log an error and still apply the other config blocks?

I think to have least surprise as a user it would be better to refuse to apply all the blocks, my reasoning is if we instead apply blocks in part we have an inconsistent view of the configuration and this would be unexpected?

Maybe I am wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or maybe we don't have the mechanism yet in place to communicate that problem to the user through the UI?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a fair question, I don't know what the user should expect in these cases. So your approach would be to "pause" the beat, and disable all modules & outputs until the configuration is not blacklisted?

We currently have a way to report an error, it refers users to the log file when that happens.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, not sure either do we want a half working beats or do we want a consistent beat?

Copy link

Choose a reason for hiding this comment

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

No matter what, we also to signal the UI that configs can not be applied due to the blacklist. Just logging the issue locally, makes it somewhat 'silent'.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, people could have access to management but don't have physical access to the machine.

@urso I think it could be done in two PR, this one to detect errors and another one to improve the feedback loop of a beats since this would certainly require UI changes to support it.


for _, block := range configs.Blocks {
if c.blacklisted(configs.Type, block) {
logp.Err("Got a blacklisted configuration, ignoring it")
Copy link
Contributor

Choose a reason for hiding this comment

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

Log which option was blacklisted?

return false
}

func (c *ConfigBlacklist) blockMatches(pattern *regexp.Regexp, segments []string, current *common.Config) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add is prefix for predicate.

x-pack/libbeat/management/blacklist.go Show resolved Hide resolved
}

return result
}
Copy link

Choose a reason for hiding this comment

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

No matter what, we also to signal the UI that configs can not be applied due to the blacklist. Just logging the issue locally, makes it somewhat 'silent'.

}

// Filter returns a copy of the given ConfigBlocks with the
func (c *ConfigBlacklist) Filter(configBlocks api.ConfigBlocks) api.ConfigBlocks {
Copy link

Choose a reason for hiding this comment

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

I'd prefer to keep the ConfigBlock api a as small as possible. Reading the code, I understand that ConfigBlock is be mostly a predicate.

e.g.

type Checker interface {
  Check(string, api.ConfigBlock) bool // return false if the config block is rejected by the checker
}

func FilterBlocks(checker Checker, blocks api.ConfigBlocks) api.ConfigBlocks {
  ...
}

func (c *ConfigBlacklist) Check(type string, blk api.ConfigBlock) bool {
  return !c.isBlacklisted(type, blk)
}

We could also wrap the Checker to log/collect all config blocks that do not match for reporting back to kibana.

As all functionality is in the management package, do we even need to export the filter function?

Copy link
Contributor

@ph ph Nov 16, 2018

Choose a reason for hiding this comment

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

Yes, it's better approach (interface)

I would say no, if we encapsulate all the checks (whitelist+blacklist) and we just check if the config is valid that removes the need do any filtering and this would probably simplify things to know what state the beats is currently in.

All config block valid => config applied
Any invalid block => do not apply the config.

Copy link
Contributor

Choose a reason for hiding this comment

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

I also thing validate should check all the checks and not fails on the first one so we can report all the errors at once in the UI.

Copy link

Choose a reason for hiding this comment

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

+1 on collecting all errors. Use multierror.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I understand the keep ConfigBlock API small comment, I don't add anything to ConfigBlock here, as isBlacklisted is part of ConfigBlacklist.

Do we agree then on treating any a single blacklisted block as a global error that will stop applying new configs? I can do the changes and introduce multierror

@ruflin ruflin added the Team:Integrations Label for the Integrations team label Nov 27, 2018
Carlos Pérez-Aradros Herce added 2 commits November 28, 2018 12:09
@ph
Copy link
Contributor

ph commented Dec 4, 2018

@exekias Just ping me if you need another look.

@exekias exekias force-pushed the cm-blacklisting branch 2 times, most recently from 1b70e4e to d92189e Compare December 10, 2018 23:16
@exekias
Copy link
Contributor Author

exekias commented Dec 11, 2018

this should be ready for another look, I added a commit to use multierror and stop applying configs on any blocked config, added a comment here: #9099 (comment)

// ConfigBlacklist takes a ConfigBlocks object and filter it based on the given
// blacklist settings
type ConfigBlacklist struct {
patterns map[string]*regexp.Regexp
Copy link

Choose a reason for hiding this comment

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

better use match.Matcher here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I will do the change in a followup PR that will include the changelog.

@ph ph merged commit 267c76e into elastic:master Dec 12, 2018
ph pushed a commit to ph/beats that referenced this pull request Dec 12, 2018
* Add Central Management blacklisting

This change allows to define local blacklist for configurations coming
from Central Management. If a configuration block matches the given
regular expession, it will be ignored:

For example:

```
management:
  blacklist:
    output: console
    metricbeat.modules.module: k.{18}s
```

(cherry picked from commit 267c76e)
@ph ph added v6.6.0 Management and removed needs_backport PR is waiting to be backported to other branches. labels Dec 12, 2018
ph added a commit that referenced this pull request Dec 13, 2018
* Add Central Management blacklisting

This change allows to define local blacklist for configurations coming
from Central Management. If a configuration block matches the given
regular expession, it will be ignored:

For example:

```
management:
  blacklist:
    output: console
    metricbeat.modules.module: k.{18}s
```

(cherry picked from commit 267c76e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants