Skip to content

Commit

Permalink
The 'export config' subcommand should display field reference instead…
Browse files Browse the repository at this point in the history
… of values (#8769) (#8817)

Change the behavior of the export config to not display the values from
the keystore or the environment.

(cherry picked from commit 47c78ee)
  • Loading branch information
ph authored Oct 31, 2018
1 parent 7861e60 commit 0f82c1e
Show file tree
Hide file tree
Showing 13 changed files with 123 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 @@ -59,3 +59,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]
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ https://github.com/elastic/beats/compare/v6.4.0...6.x[Check the HEAD diff]
- Fix race condition when publishing monitoring data. {pull}8646[8646]
- Fix bug in loading dashboards from zip file. {issue}8051[8051]
- Fix in-cluster kubernetes configuration on IPv6. {pull}8754[8754]
- 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 0f82c1e

Please sign in to comment.