Skip to content

Commit

Permalink
The 'export config' subcommand should display field reference instead of
Browse files Browse the repository at this point in the history
values

Change the behavior of the export config to not display the values from
the keystore or the environment.
  • Loading branch information
ph committed Oct 30, 2018
1 parent 51c1aa2 commit 5d75a65
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-developer.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ The list below covers the major changes between 6.3.0 and master only.
- Add `mage.GenerateModuleReferenceConfig` for generating reference config files that include configuration sections from the module directory. {pull}8615[8615]
- Add `mage.GenerateFieldsGo` for generating fields.go files. {pull}8615[8615]
- Add `mage.KibanaDashboards` for collecting Kibana dashboards and generating index patterns. {pull}8615[8615]
- Allow to disable config resolver using the `Settings.DisableConfigResolver` field when initializing libbeat. {pull}8769[8769]
2 changes: 2 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ https://github.com/elastic/beats/compare/v6.4.0...master[Check the HEAD diff]
- Fix race condition when publishing monitoring data. {pull}8646[8646]
- Fix in-cluster kubernetes configuration on IPv6. {pull}8754[8754]
- Fix bug in loading dashboards from zip file. {issue}8051[8051]
- The export config subcommand should not display real value for field reference. {pull}xxx[xxx]
- The export config subcommand should not display real value for field reference. {pull}8769[8769]

*Auditbeat*

Expand Down
4 changes: 2 additions & 2 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -567,8 +567,8 @@ Apache License 2.0

--------------------------------------------------------------------
Dependency: github.com/elastic/go-ucfg
Version: v0.6.4
Revision: e81c02ad8f1ab46b9e8b07f0832245c0c2e1d13c
Version: v0.6.5
Revision: 92d43887f91851c9936621665af7f796f4d03412
License type (autodetected): Apache-2.0
./vendor/github.com/elastic/go-ucfg/LICENSE:
--------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions libbeat/cmd/export/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func exportConfig(settings instance.Settings, name, idxPrefix, beatVersion strin
return fmt.Errorf("error initializing beat: %s", err)
}

settings.DisableConfigResolver = true

err = b.InitWithSettings(settings)
if err != nil {
return fmt.Errorf("error initializing beat: %s", err)
Expand Down
35 changes: 31 additions & 4 deletions libbeat/cmd/instance/beat.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (

"github.com/elastic/go-sysinfo"
"github.com/elastic/go-sysinfo/types"
ucfg "github.com/elastic/go-ucfg"

"github.com/elastic/beats/libbeat/api"
"github.com/elastic/beats/libbeat/asset"
Expand Down Expand Up @@ -149,12 +150,13 @@ func init() {
// CryptGenRandom is used.
func initRand() {
n, err := cryptRand.Int(cryptRand.Reader, big.NewInt(math.MaxInt64))
seed := n.Int64()
var seed int64
if err != nil {
// fallback to current timestamp
seed = time.Now().UnixNano()
} else {
seed = n.Int64()
}

rand.Seed(seed)
}

Expand Down Expand Up @@ -563,8 +565,13 @@ func (b *Beat) configure(settings Settings) error {
return fmt.Errorf("could not initialize the keystore: %v", err)
}

// TODO: Allow the options to be more flexible for dynamic changes
common.OverwriteConfigOpts(keystore.ConfigOpts(store))
if settings.DisableConfigResolver {
common.OverwriteConfigOpts(obfuscateConfigOpts())
} else {
// TODO: Allow the options to be more flexible for dynamic changes
common.OverwriteConfigOpts(configOpts(store))
}

b.keystore = store
err = cloudid.OverwriteSettings(cfg)
if err != nil {
Expand Down Expand Up @@ -880,3 +887,23 @@ func logSystemInfo(info beat.Info) {
}
}
}

// configOpts returns ucfg config options with a resolver linked to the current keystore.
// TODO: Refactor to allow insert into the config option array without having to redefine everything
func configOpts(store keystore.Keystore) []ucfg.Option {
return []ucfg.Option{
ucfg.PathSep("."),
ucfg.Resolve(keystore.ResolverWrap(store)),
ucfg.ResolveEnv,
ucfg.VarExp,
}
}

// obfuscateConfigOpts disables any resolvers in the configuration, instead we return the field
// reference string directly.
func obfuscateConfigOpts() []ucfg.Option {
return []ucfg.Option{
ucfg.PathSep("."),
ucfg.ResolveNOOP,
}
}
13 changes: 7 additions & 6 deletions libbeat/cmd/instance/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ import (

// Settings contains basic settings for any beat to pass into GenRootCmd
type Settings struct {
Name string
IndexPrefix string
Version string
Monitoring report.Settings
RunFlags *pflag.FlagSet
ConfigOverrides *common.Config
Name string
IndexPrefix string
Version string
Monitoring report.Settings
RunFlags *pflag.FlagSet
ConfigOverrides *common.Config
DisableConfigResolver bool
}
11 changes: 0 additions & 11 deletions libbeat/keystore/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,3 @@ func ResolverWrap(keystore Keystore) func(string) (string, error) {
return string(v), nil
}
}

// ConfigOpts returns ucfg config options with a resolver linked to the current keystore.
// TODO: Refactor to allow insert into the config option array without having to redefine everything
func ConfigOpts(keystore Keystore) []ucfg.Option {
return []ucfg.Option{
ucfg.PathSep("."),
ucfg.Resolve(ResolverWrap(keystore)),
ucfg.ResolveEnv,
ucfg.VarExp,
}
}
22 changes: 15 additions & 7 deletions libbeat/tests/system/beat/beat.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,35 @@ class Proc(object):
the object gets collected.
"""

def __init__(self, args, outputfile):
def __init__(self, args, outputfile, env={}):
self.args = args
self.output = open(outputfile, "ab")
self.stdin_read, self.stdin_write = os.pipe()
self.env = env

def start(self):

if sys.platform.startswith("win"):
# ensure that the environment is inherited to the subprocess.
variables = os.environ.copy()
variables = variables.update(self.env)

self.proc = subprocess.Popen(
self.args,
stdin=self.stdin_read,
stdout=self.output,
stderr=subprocess.STDOUT,
bufsize=0,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,
env=variables)
else:
self.proc = subprocess.Popen(
self.args,
stdin=self.stdin_read,
stdout=self.output,
stderr=subprocess.STDOUT,
bufsize=0,
)
env=self.env)
# If a "No such file or directory" error points you here, run
# "make metricbeat.test" on metricbeat folder
return self.proc
Expand Down Expand Up @@ -145,15 +151,16 @@ def run_beat(self,
output=None,
logging_args=["-e", "-v", "-d", "*"],
extra_args=[],
exit_code=None):
exit_code=None,
env={}):
"""
Executes beat.
Waits for the process to finish before returning to
the caller.
"""
proc = self.start_beat(cmd=cmd, config=config, output=output,
logging_args=logging_args,
extra_args=extra_args)
extra_args=extra_args, env=env)
if exit_code != None:
return proc.check_wait(exit_code)

Expand All @@ -164,7 +171,8 @@ def start_beat(self,
config=None,
output=None,
logging_args=["-e", "-v", "-d", "*"],
extra_args=[]):
extra_args=[],
env={}):
"""
Starts beat and returns the process handle. The
caller is responsible for stopping / waiting for the
Expand Down Expand Up @@ -195,7 +203,7 @@ def start_beat(self,
if extra_args:
args.extend(extra_args)

proc = Proc(args, os.path.join(self.working_dir, output))
proc = Proc(args, os.path.join(self.working_dir, output), env)
proc.start()
return proc

Expand Down
18 changes: 18 additions & 0 deletions libbeat/tests/system/test_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,24 @@ def test_export_config(self):
assert self.log_contains("filename: mockbeat")
assert self.log_contains("period: 1234")

def test_export_config_environment_variable(self):
"""
Test export config works but doesn"t expose environment variable.
"""
self.render_config_template("mockbeat",
os.path.join(self.working_dir,
"libbeat.yml"),
metrics_period="${METRIC_PERIOD}")

exit_code = self.run_beat(
logging_args=[],
extra_args=["export", "config"],
config="libbeat.yml", env={'METRIC_PERIOD': '1234'})

assert exit_code == 0
assert self.log_contains("filename: mockbeat")
assert self.log_contains("period: ${METRIC_PERIOD}")

def test_export_template(self):
"""
Test export template works
Expand Down
21 changes: 21 additions & 0 deletions libbeat/tests/system/test_keystore.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,24 @@ def test_keystore_with_nested_key(self):
self.wait_until(lambda: self.log_contains("Elasticsearch url: http://myeleasticsearchsecrethost:9200"))
assert self.log_contains(secret)
proc.check_kill_and_wait()

def test_export_config_with_keystore(self):
"""
Test export config works and doesn't expose keystore value
"""
key = "asecret"
secret = "asecretvalue"

self.render_config_template(keystore_path=self.keystore_path, elasticsearch={
'hosts': "${%s}" % key
})

exit_code = self.run_beat(extra_args=["keystore", "create"])
assert exit_code == 0

self.add_secret(key, value=secret)
exit_code = self.run_beat(extra_args=["export", "config"])

assert exit_code == 0
assert self.log_contains(secret) == False
assert self.log_contains("${%s}" % key)
8 changes: 7 additions & 1 deletion vendor/github.com/elastic/go-ucfg/CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions vendor/github.com/elastic/go-ucfg/opts.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions vendor/vendor.json
Original file line number Diff line number Diff line change
Expand Up @@ -1002,12 +1002,12 @@
"versionExact": "v0.0.3"
},
{
"checksumSHA1": "+FZjRtpNIIvf+ZteS0y6IGw/JA8=",
"checksumSHA1": "Yb61Nqnh+3igFci61hv9WYgk/hc=",
"path": "github.com/elastic/go-ucfg",
"revision": "e81c02ad8f1ab46b9e8b07f0832245c0c2e1d13c",
"revisionTime": "2018-10-05T15:55:04Z",
"version": "v0.6.4",
"versionExact": "v0.6.4"
"revision": "92d43887f91851c9936621665af7f796f4d03412",
"revisionTime": "2018-10-26T17:42:06Z",
"version": "v0.6.5",
"versionExact": "v0.6.5"
},
{
"checksumSHA1": "X+R/CD8SokJrmlxFTx2nSevRDhQ=",
Expand Down

0 comments on commit 5d75a65

Please sign in to comment.