-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Conversation
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 ```
return fmt.Errorf("wrong type, expect map") | ||
} | ||
|
||
var expand func(key string, value interface{}) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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'.
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
fad7435
to
e91a844
Compare
} | ||
|
||
return result | ||
} |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
6165c5b
to
0ac34dc
Compare
@exekias Just ping me if you need another look. |
1b70e4e
to
d92189e
Compare
d92189e
to
7dd370e
Compare
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
* 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)
* 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)
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: