diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9afdb30753d..98700ce9414 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -101,6 +101,7 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff] *Affecting all Beats* +- Allow users to enable features via configuration, starting with the FQDN reporting feature. {issue}1070[1070] {pull}34456[34456] *Auditbeat* diff --git a/NOTICE.txt b/NOTICE.txt index 2e33c5e6336..feb37019a44 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -8457,11 +8457,11 @@ third-party archives. -------------------------------------------------------------------------------- Dependency : github.com/docker/docker -Version: v20.10.12+incompatible +Version: v20.10.22+incompatible Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/docker/docker@v20.10.12+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/docker/docker@v20.10.22+incompatible/LICENSE: Apache License @@ -9071,11 +9071,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-plugins-help -------------------------------------------------------------------------------- Dependency : github.com/docker/go-units -Version: v0.4.0 +Version: v0.5.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/docker/go-units@v0.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/docker/go-units@v0.5.0/LICENSE: Apache License @@ -9867,11 +9867,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-a -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-client/v7 -Version: v7.0.3 +Version: v7.0.3-0.20230315204017-166fd1fd746f Licence type (autodetected): Elastic -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-client/v7@v7.0.3/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-client/v7@v7.0.3-0.20230315204017-166fd1fd746f/LICENSE.txt: ELASTIC LICENSE AGREEMENT @@ -10100,11 +10100,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.2.16 +Version: v0.3.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.2.16/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.3.3/LICENSE: Apache License Version 2.0, January 2004 @@ -10414,11 +10414,11 @@ these terms. -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-system-metrics -Version: v0.4.6 +Version: v0.4.6-0.20230308003052-ba171438211e Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-system-metrics@v0.4.6/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-system-metrics@v0.4.6-0.20230308003052-ba171438211e/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -12354,11 +12354,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-structform@v -------------------------------------------------------------------------------- Dependency : github.com/elastic/go-sysinfo -Version: v1.9.0 +Version: v1.9.1-0.20230215152520-f544eca983fb Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.9.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.9.1-0.20230215152520-f544eca983fb/LICENSE.txt: Apache License @@ -18401,11 +18401,11 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice -------------------------------------------------------------------------------- Dependency : github.com/mitchellh/hashstructure -Version: v0.0.0-20170116052023-ab25296c0f51 +Version: v1.1.0 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/hashstructure@v0.0.0-20170116052023-ab25296c0f51/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/hashstructure@v1.1.0/LICENSE: The MIT License (MIT) @@ -19087,11 +19087,11 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.30 -------------------------------------------------------------------------------- Dependency : github.com/prometheus/procfs -Version: v0.8.0 +Version: v0.9.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.8.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.9.0/LICENSE: Apache License Version 2.0, January 2004 @@ -22207,11 +22207,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/sync -Version: v0.0.0-20220929204114-8fcdb60fdcc0 +Version: v0.1.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/sync@v0.0.0-20220929204114-8fcdb60fdcc0/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/sync@v0.1.0/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -22244,11 +22244,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/sys -Version: v0.2.0 +Version: v0.6.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.6.0/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -22318,11 +22318,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/time -Version: v0.0.0-20220609170525-579cf78fd858 +Version: v0.3.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.0.0-20220609170525-579cf78fd858/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.3.0/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. @@ -31512,214 +31512,13 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/containerd/containerd -Version: v1.5.13 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/containerd/containerd@v1.5.13/LICENSE: - - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -------------------------------------------------------------------------------- Dependency : github.com/creack/pty -Version: v1.1.11 +Version: v1.1.18 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/creack/pty@v1.1.11/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/creack/pty@v1.1.18/LICENSE: Copyright (c) 2011 Keith Rarick @@ -41402,11 +41201,11 @@ Contents of probable licence file $GOMODCACHE/github.com/moby/spdystream@v0.2.0/ -------------------------------------------------------------------------------- Dependency : github.com/moby/term -Version: v0.0.0-20210610120745-9d4ed1856297 +Version: v0.0.0-20221205130635-1aeaba878587 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/moby/term@v0.0.0-20210610120745-9d4ed1856297/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/moby/term@v0.0.0-20221205130635-1aeaba878587/LICENSE: Apache License @@ -43989,11 +43788,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : github.com/sirupsen/logrus -Version: v1.8.1 +Version: v1.9.0 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/sirupsen/logrus@v1.8.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/sirupsen/logrus@v1.9.0/LICENSE: The MIT License (MIT) @@ -47522,11 +47321,11 @@ limitations under the License. -------------------------------------------------------------------------------- Dependency : gotest.tools/v3 -Version: v3.0.3 +Version: v3.4.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gotest.tools/v3@v3.0.3/LICENSE: +Contents of probable licence file $GOMODCACHE/gotest.tools/v3@v3.4.0/LICENSE: Copyright 2018 gotest.tools authors diff --git a/auditbeat/auditbeat.reference.yml b/auditbeat/auditbeat.reference.yml index 536d7a8481e..483bbe1cfb0 100644 --- a/auditbeat/auditbeat.reference.yml +++ b/auditbeat/auditbeat.reference.yml @@ -1715,3 +1715,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/auditbeat/docs/configuring-howto.asciidoc b/auditbeat/docs/configuring-howto.asciidoc index 65938efb9c7..a2de4ee5ed6 100644 --- a/auditbeat/docs/configuring-howto.asciidoc +++ b/auditbeat/docs/configuring-howto.asciidoc @@ -25,6 +25,7 @@ include::{libbeat-dir}/shared/configuring-intro.asciidoc[] * <> * <> * <> +* <> * <<{beatname_lc}-reference-yml>> After changing configuration settings, you need to restart {beatname_uc} to @@ -64,4 +65,6 @@ include::{libbeat-dir}/regexp.asciidoc[] include::{libbeat-dir}/shared-instrumentation.asciidoc[] +include::{libbeat-dir}/shared-feature-flags.asciidoc[] + include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/dev-tools/notice/overrides.json b/dev-tools/notice/overrides.json index 6a935ca1a87..52024e4f77c 100644 --- a/dev-tools/notice/overrides.json +++ b/dev-tools/notice/overrides.json @@ -1,4 +1,5 @@ {"name": "github.com/elastic/elastic-agent-client/v7", "licenceType": "Elastic"} +{"name": "github.com/ycombinator/elastic-agent-client/v7", "licenceType": "Elastic"} {"name": "github.com/elastic/elastic-agent-shipper-client", "licenceType": "Elastic"} {"name": "github.com/gorhill/cronexpr", "licenceType": "Apache-2.0", "licenceFile":"APLv2"} {"name": "github.com/hashicorp/cronexpr", "licenceType": "Apache-2.0", "licenceFile":"APLv2"} diff --git a/filebeat/beater/filebeat.go b/filebeat/beater/filebeat.go index ad28e293efd..7a9812cabdb 100644 --- a/filebeat/beater/filebeat.go +++ b/filebeat/beater/filebeat.go @@ -190,9 +190,9 @@ func (fb *Filebeat) setupPipelineLoaderCallback(b *beat.Beat) error { modulesFactory := fileset.NewSetupFactory(b.Info, pipelineLoaderFactory, enableAllFilesets) if fb.config.ConfigModules.Enabled() { if enableAllFilesets { - //All module configs need to be loaded to enable all the filesets - //contained in the modules. The default glob just loads the enabled - //ones. Switching the glob pattern from *.yml to * achieves this. + // All module configs need to be loaded to enable all the filesets + // contained in the modules. The default glob just loads the enabled + // ones. Switching the glob pattern from *.yml to * achieves this. origPath, _ := fb.config.ConfigModules.String("path", -1) newPath := strings.TrimSuffix(origPath, ".yml") _ = fb.config.ConfigModules.SetString("path", -1, newPath) diff --git a/filebeat/config/config.go b/filebeat/config/config.go index bd665a338fb..7b73c2eb602 100644 --- a/filebeat/config/config.go +++ b/filebeat/config/config.go @@ -119,7 +119,7 @@ func mergeConfigFiles(configFiles []string, config *Config) error { return nil } -// Fetches and merges all config files given by configDir. All are put into one config object +// FetchConfigs fetches and merges all config files given by configDir. All are put into one config object func (config *Config) FetchConfigs() error { configDir := config.ConfigDir diff --git a/filebeat/docs/configuring-howto.asciidoc b/filebeat/docs/configuring-howto.asciidoc index 8bd08a838ef..182827a784c 100644 --- a/filebeat/docs/configuring-howto.asciidoc +++ b/filebeat/docs/configuring-howto.asciidoc @@ -28,6 +28,7 @@ include::{libbeat-dir}/shared/configuring-intro.asciidoc[] * <> * <> * <> +* <> * <<{beatname_lc}-reference-yml>> -- @@ -73,4 +74,6 @@ include::{libbeat-dir}/regexp.asciidoc[] include::{libbeat-dir}/shared-instrumentation.asciidoc[] +include::{libbeat-dir}/shared-feature-flags.asciidoc[] + include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/filebeat/filebeat.reference.yml b/filebeat/filebeat.reference.yml index e6935b569bb..55cf8559c8d 100644 --- a/filebeat/filebeat.reference.yml +++ b/filebeat/filebeat.reference.yml @@ -2798,3 +2798,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/go.mod b/go.mod index b4cb14a3ad1..dc690d7aa9b 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 github.com/Azure/go-autorest/autorest/date v0.3.0 github.com/Masterminds/semver v1.5.0 - github.com/Microsoft/go-winio v0.5.2 + github.com/Microsoft/go-winio v0.6.0 github.com/PaesslerAG/gval v1.0.0 github.com/PaesslerAG/jsonpath v0.1.1 github.com/Shopify/sarama v1.27.0 @@ -60,17 +60,17 @@ require ( github.com/devigned/tab v0.1.2-0.20190607222403-0c15cf42f9a2 // indirect github.com/dgraph-io/badger/v3 v3.2103.1 github.com/digitalocean/go-libvirt v0.0.0-20180301200012-6075ea3c39a1 - github.com/docker/docker v20.10.12+incompatible + github.com/docker/docker v20.10.22+incompatible github.com/docker/go-connections v0.4.0 github.com/docker/go-plugins-helpers v0.0.0-20181025120712-1e6269c305b8 - github.com/docker/go-units v0.4.0 + github.com/docker/go-units v0.5.0 github.com/dolmen-go/contextio v0.0.0-20200217195037-68fc5150bcd5 github.com/dop251/goja v0.0.0-20200831102558-9af81ddcf0e1 github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 github.com/dustin/go-humanize v1.0.0 github.com/eapache/go-resiliency v1.2.0 github.com/eclipse/paho.mqtt.golang v1.3.5 - github.com/elastic/elastic-agent-client/v7 v7.0.3 + github.com/elastic/elastic-agent-client/v7 v7.0.3-0.20230315204017-166fd1fd746f github.com/elastic/go-concert v0.2.0 github.com/elastic/go-libaudit/v2 v2.3.2 github.com/elastic/go-licenser v0.4.0 @@ -79,7 +79,7 @@ require ( github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595 github.com/elastic/go-seccomp-bpf v1.3.0 github.com/elastic/go-structform v0.0.10 - github.com/elastic/go-sysinfo v1.9.0 + github.com/elastic/go-sysinfo v1.9.1-0.20230215152520-f544eca983fb github.com/elastic/go-ucfg v0.8.6 github.com/elastic/gosigar v0.14.2 github.com/fatih/color v1.13.0 @@ -123,7 +123,7 @@ require ( github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe // indirect github.com/miekg/dns v1.1.42 github.com/mitchellh/gox v1.0.1 - github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51 + github.com/mitchellh/hashstructure v1.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/olekukonko/tablewriter v0.0.5 github.com/osquery/osquery-go v0.0.0-20210622151333-99b4efa62ec5 @@ -133,7 +133,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.30.0 - github.com/prometheus/procfs v0.8.0 + github.com/prometheus/procfs v0.9.0 github.com/prometheus/prometheus v1.8.2-0.20210701133801-b0944590a1c9 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 github.com/samuel/go-parser v0.0.0-20130731160455-ca8abbf65d0e // indirect @@ -159,10 +159,10 @@ require ( golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 golang.org/x/net v0.2.0 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 - golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 - golang.org/x/sys v0.2.0 + golang.org/x/sync v0.1.0 + golang.org/x/sys v0.6.0 golang.org/x/text v0.4.0 - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 + golang.org/x/time v0.3.0 golang.org/x/tools v0.1.12 google.golang.org/api v0.100.0 google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c @@ -193,9 +193,9 @@ require ( github.com/awslabs/kinesis-aggregation/go/v2 v2.0.0-20220623125934-28468a6701b5 github.com/elastic/bayeux v1.0.5 github.com/elastic/elastic-agent-autodiscover v0.5.0 - github.com/elastic/elastic-agent-libs v0.2.16 + github.com/elastic/elastic-agent-libs v0.3.3 github.com/elastic/elastic-agent-shipper-client v0.4.0 - github.com/elastic/elastic-agent-system-metrics v0.4.6 + github.com/elastic/elastic-agent-system-metrics v0.4.6-0.20230308003052-ba171438211e github.com/elastic/go-elasticsearch/v8 v8.2.0 github.com/elastic/mito v0.0.0-20230302005114-1dda06e81678 github.com/elastic/toutoumomoma v0.0.0-20221026030040-594ef30cb640 @@ -246,7 +246,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.10 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/containerd/containerd v1.5.13 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect @@ -316,7 +315,7 @@ require ( github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/tklauser/go-sysconf v0.3.9 // indirect @@ -351,7 +350,7 @@ require ( github.com/docker/distribution v2.8.1+incompatible // indirect github.com/godbus/dbus/v5 v5.0.6 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/yuin/gopher-lua v0.0.0-20170403160031-b402f3114ec7 // indirect gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index be152685f6d..fb4d713d276 100644 --- a/go.sum +++ b/go.sum @@ -98,7 +98,6 @@ github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxw github.com/Azure/go-amqp v0.16.0 h1:6mhxUxaKLjMtHlGqzeih/LKqjUPLZxbM6zwfz5/C4NQ= github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -441,7 +440,6 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7 github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.13 h1:XqvKw9i4P7/mFrC3TSM7yV5cwFZ9avXe6M3YANKnzEE= github.com/containerd/containerd v1.5.13/go.mod h1:3AlCrzKROjIuP3JALsY14n8YtntaUDBu7vek+rPN5Vc= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -519,8 +517,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= @@ -570,8 +568,9 @@ github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6 github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20170802015333-8af4db6f002a/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U= github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.22+incompatible h1:6jX4yB+NtcbldT90k7vBSaWJDB3i+zkVJT9BEK8kQkk= +github.com/docker/docker v20.10.22+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -580,8 +579,9 @@ github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -611,15 +611,15 @@ github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 h1:lnDkqiRFKm0rxdljqr github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY= github.com/elastic/elastic-agent-autodiscover v0.5.0 h1:fiDJQKB148RsRISqqbGINtJ/ZPupeVjwn0fbPz9ZDOc= github.com/elastic/elastic-agent-autodiscover v0.5.0/go.mod h1:p3MSf9813JEnolCTD0GyVAr3+Eptg2zQ9aZVFjl4tJ4= -github.com/elastic/elastic-agent-client/v7 v7.0.3 h1:YqZPnO7Z9rlj25sFZEUaxGGK3mZR4v0uSOcfO8GRv7s= -github.com/elastic/elastic-agent-client/v7 v7.0.3/go.mod h1:cHviLpA5fAwMbfBIHBVNl16qp90bO7pKHMAQaG+9raU= +github.com/elastic/elastic-agent-client/v7 v7.0.3-0.20230315204017-166fd1fd746f h1:IzNUtc4ZfDSUHbRI5Yz5tJ+lt9N75cxvlT9aXW2Hh2g= +github.com/elastic/elastic-agent-client/v7 v7.0.3-0.20230315204017-166fd1fd746f/go.mod h1:UlVOHSDvTA4Mfdhdg+BE7aqOsUR3ab+x2Zl0aHlBXs4= github.com/elastic/elastic-agent-libs v0.2.11/go.mod h1:chO3rtcLyGlKi9S0iGVZhYCzDfdDsAQYBc+ui588AFE= -github.com/elastic/elastic-agent-libs v0.2.16 h1:31/VlnRp2ko0CMg+sm7b/u3vOPIlFXgMkJn/8uS6EbU= -github.com/elastic/elastic-agent-libs v0.2.16/go.mod h1:0J9lzJh+BjttIiVjYDLncKYCEWUUHiiqnuI64y6C6ss= +github.com/elastic/elastic-agent-libs v0.3.3 h1:iE8XhqQ0zRBLba+eu6ScZED0DYcVP/r2JvjcVoOkxic= +github.com/elastic/elastic-agent-libs v0.3.3/go.mod h1:nRkcK96PSJfK232cJRx17n9+/MVAIOzs5ghZdzXJAMo= github.com/elastic/elastic-agent-shipper-client v0.4.0 h1:nsTJF9oo4RHLl+zxFUZqNHaE86C6Ba5aImfegcEf6Sk= github.com/elastic/elastic-agent-shipper-client v0.4.0/go.mod h1:OyI2W+Mv3JxlkEF3OeT7K0dbuxvwew8ke2Cf4HpLa9Q= -github.com/elastic/elastic-agent-system-metrics v0.4.6 h1:SDiI62M68eNcpnihHkHfQ/Aqxh4eSf5zuoD9yBv2MPc= -github.com/elastic/elastic-agent-system-metrics v0.4.6/go.mod h1:vTqfhtj83LlPKbusEwrEywZv13nhPExwINB3PkeRQeo= +github.com/elastic/elastic-agent-system-metrics v0.4.6-0.20230308003052-ba171438211e h1:OIfumgZhI6lI7Qy1KD1VzuqvX9DWSBpXJsvj97s7MRM= +github.com/elastic/elastic-agent-system-metrics v0.4.6-0.20230308003052-ba171438211e/go.mod h1:v/t/qgYueW3ZOm7SZhYY3ng9GWDddDLu7pmG4Ra3PBs= github.com/elastic/elastic-transport-go/v8 v8.1.0 h1:NeqEz1ty4RQz+TVbUrpSU7pZ48XkzGWQj02k5koahIE= github.com/elastic/elastic-transport-go/v8 v8.1.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270 h1:cWPqxlPtir4RoQVCpGSRXmLqjEHpJKbR60rxh1nQZY4= @@ -647,8 +647,8 @@ github.com/elastic/go-structform v0.0.9/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZN github.com/elastic/go-structform v0.0.10 h1:oy08o/Ih2hHTkNcRY/1HhaYvIp5z6t8si8gnCJPDo1w= github.com/elastic/go-structform v0.0.10/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZNqAFnwKR4OrIM4= github.com/elastic/go-sysinfo v1.7.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-sysinfo v1.9.0 h1:usICqY/Nw4Mpn9f4LdtpFrKxXroJDe81GaxxUlCckIo= -github.com/elastic/go-sysinfo v1.9.0/go.mod h1:eBD1wEGVaRnRLGecc9iG1z8eOv5HnEdz9+nWd8UAxcE= +github.com/elastic/go-sysinfo v1.9.1-0.20230215152520-f544eca983fb h1:dTYv5aVpYzI53KJwDM/Hue68YU/PHkLJD/5jDl1fGSs= +github.com/elastic/go-sysinfo v1.9.1-0.20230215152520-f544eca983fb/go.mod h1:j/gGAinRS+z3loQ/1pO+s9pCyQsna8U13kqhF1Aa0fg= github.com/elastic/go-ucfg v0.8.5/go.mod h1:4E8mPOLSUV9hQ7sgLEJ4bvt0KhMuDJa8joDT2QGAEKA= github.com/elastic/go-ucfg v0.8.6 h1:stUeyh2goTgGX+/wb9gzKvTv0YB0231LTpKUgCKj4U0= github.com/elastic/go-ucfg v0.8.6/go.mod h1:4E8mPOLSUV9hQ7sgLEJ4bvt0KhMuDJa8joDT2QGAEKA= @@ -1354,8 +1354,8 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= -github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51 h1:qdHlMllk/PTLUrX3XdtXDrLL1lPSfcqUmJD1eYfbapg= -github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -1377,8 +1377,8 @@ github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 h1:yH0SvLzcbZxcJXho2yh7CqdENGMQe73Cw3woZBpPli0= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1590,8 +1590,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/prometheus v0.0.0-20200609090129-a6600f564e3c/go.mod h1:S5n0C6tSgdnwWshBUceRx5G1OsjLv/EeZ9t3wIfEtsY= github.com/prometheus/prometheus v1.8.2-0.20210701133801-b0944590a1c9 h1:If7jYp33vwa8ZQ7GGwrAs0SBjiW0aWeAB/oV1aG7bZ4= github.com/prometheus/prometheus v1.8.2-0.20210701133801-b0944590a1c9/go.mod h1:A97P+iwS3Ffpxpejz4+ASZl6i9EqSJDzxObq8DjV2SU= @@ -1656,8 +1656,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -2081,8 +2082,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2217,8 +2218,9 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2247,8 +2249,8 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2584,8 +2586,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/gotestsum v1.7.0 h1:RwpqwwFKBAa2h+F6pMEGpE707Edld0etUD3GhqqhDNc= gotest.tools/gotestsum v1.7.0/go.mod h1:V1m4Jw3eBerhI/A6qCxUE07RnCg7ACkKj9BYcAm09V8= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/heartbeat/docs/configuring-howto.asciidoc b/heartbeat/docs/configuring-howto.asciidoc index fa312e5d4ac..c4df4343255 100644 --- a/heartbeat/docs/configuring-howto.asciidoc +++ b/heartbeat/docs/configuring-howto.asciidoc @@ -24,6 +24,7 @@ include::{libbeat-dir}/shared/configuring-intro.asciidoc[] * <> * <> * <> +* <> * <<{beatname_lc}-reference-yml>> -- @@ -66,4 +67,6 @@ include::{libbeat-dir}/regexp.asciidoc[] include::{libbeat-dir}/shared-instrumentation.asciidoc[] +include::{libbeat-dir}/shared-feature-flags.asciidoc[] + include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/heartbeat/heartbeat.reference.yml b/heartbeat/heartbeat.reference.yml index 9b52eb7fe5d..3c19678c936 100644 --- a/heartbeat/heartbeat.reference.yml +++ b/heartbeat/heartbeat.reference.yml @@ -1807,3 +1807,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/libbeat/_meta/config/default.reference.yml.tmpl b/libbeat/_meta/config/default.reference.yml.tmpl index 7919bd0d4f7..073340343d8 100644 --- a/libbeat/_meta/config/default.reference.yml.tmpl +++ b/libbeat/_meta/config/default.reference.yml.tmpl @@ -21,3 +21,4 @@ {{template "seccomp.reference.yml.tmpl" .}} {{template "instrumentation.reference.yml.tmpl" .}} {{template "migration.yml.tmpl" .}} +{{template "feature-flags.reference.yml.tmpl" .}} diff --git a/libbeat/_meta/config/feature-flags.reference.yml.tmpl b/libbeat/_meta/config/feature-flags.reference.yml.tmpl new file mode 100644 index 00000000000..7d69f3a30c3 --- /dev/null +++ b/libbeat/_meta/config/feature-flags.reference.yml.tmpl @@ -0,0 +1,6 @@ +{{ header "Feature Flags" }} + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true diff --git a/libbeat/beat/info.go b/libbeat/beat/info.go index 078833b3bde..e1068d17ff5 100644 --- a/libbeat/beat/info.go +++ b/libbeat/beat/info.go @@ -31,6 +31,7 @@ type Info struct { ElasticLicensed bool // Whether the beat is licensed under and Elastic License Name string // configured beat name Hostname string // hostname + FQDN string // FQDN ID uuid.UUID // ID assigned to beat machine EphemeralID uuid.UUID // ID assigned to beat process invocation (PID) FirstStart time.Time // The time of the first start of the Beat. @@ -41,3 +42,11 @@ type Info struct { DefaultUsername string // The default username to be used to connect to Elasticsearch Monitoring } } + +func (i Info) FQDNAwareHostname(useFQDN bool) string { + if useFQDN { + return i.FQDN + } + + return i.Hostname +} diff --git a/libbeat/beat/info_test.go b/libbeat/beat/info_test.go new file mode 100644 index 00000000000..0e3095a0470 --- /dev/null +++ b/libbeat/beat/info_test.go @@ -0,0 +1,51 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package beat + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFQDNAwareHostname(t *testing.T) { + info := Info{ + Hostname: "foo", + FQDN: "foo.bar.internal", + } + cases := map[string]struct { + useFQDN bool + want string + }{ + "fqdn_flag_enabled": { + useFQDN: true, + want: "foo.bar.internal", + }, + "fqdn_flag_disabled": { + useFQDN: false, + want: "foo", + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + got := info.FQDNAwareHostname(tc.useFQDN) + require.Equal(t, tc.want, got) + }) + } +} diff --git a/libbeat/cmd/instance/beat.go b/libbeat/cmd/instance/beat.go index 0324bb6d02d..de9e171da7b 100644 --- a/libbeat/cmd/instance/beat.go +++ b/libbeat/cmd/instance/beat.go @@ -52,6 +52,7 @@ import ( "github.com/elastic/beats/v7/libbeat/common/seccomp" "github.com/elastic/beats/v7/libbeat/dashboards" "github.com/elastic/beats/v7/libbeat/esleg/eslegclient" + "github.com/elastic/beats/v7/libbeat/features" "github.com/elastic/beats/v7/libbeat/idxmgmt" "github.com/elastic/beats/v7/libbeat/instrumentation" "github.com/elastic/beats/v7/libbeat/kibana" @@ -79,9 +80,9 @@ import ( libversion "github.com/elastic/elastic-agent-libs/version" "github.com/elastic/elastic-agent-system-metrics/metric/system/host" metricreport "github.com/elastic/elastic-agent-system-metrics/report" - sysinfo "github.com/elastic/go-sysinfo" + "github.com/elastic/go-sysinfo" "github.com/elastic/go-sysinfo/types" - ucfg "github.com/elastic/go-ucfg" + "github.com/elastic/go-ucfg" ) // Beat provides the runnable and configurable instance of a beat. @@ -108,7 +109,8 @@ type beatConfig struct { MaxProcs int `config:"max_procs"` GCPercent int `config:"gc_percent"` - Seccomp *config.C `config:"seccomp"` + Seccomp *config.C `config:"seccomp"` + Features *config.C `config:"features"` // beat internal components configurations HTTP *config.C `config:"http"` @@ -211,6 +213,12 @@ func NewBeat(name, indexPrefix, v string, elasticLicensed bool) (*Beat, error) { return nil, err } + h, err := sysinfo.Host() + if err != nil { + return nil, fmt.Errorf("failed to get host information: %w", err) + } + fqdn := h.Info().FQDN + fields, err := asset.GetFields(name) if err != nil { return nil, err @@ -229,6 +237,7 @@ func NewBeat(name, indexPrefix, v string, elasticLicensed bool) (*Beat, error) { Version: v, Name: hostname, Hostname: hostname, + FQDN: fqdn, ID: id, FirstStart: time.Now(), StartTime: time.Now(), @@ -503,7 +512,6 @@ func (b *Beat) registerMetrics() { monitoring.NewString(infoRegistry, "version").Set(b.Info.Version) monitoring.NewString(infoRegistry, "beat").Set(b.Info.Beat) monitoring.NewString(infoRegistry, "name").Set(b.Info.Name) - monitoring.NewString(infoRegistry, "hostname").Set(b.Info.Hostname) monitoring.NewString(infoRegistry, "uuid").Set(b.Info.ID.String()) monitoring.NewString(infoRegistry, "ephemeral_id").Set(b.Info.EphemeralID.String()) monitoring.NewString(infoRegistry, "binary_arch").Set(runtime.GOARCH) @@ -536,9 +544,18 @@ func (b *Beat) registerMetrics() { // state.beat beatRegistry := stateRegistry.NewRegistry("beat") monitoring.NewString(beatRegistry, "name").Set(b.Info.Name) +} + +func (b *Beat) RegisterHostname(useFQDN bool) { + hostname := b.Info.FQDNAwareHostname(useFQDN) + + // info.hostname + infoRegistry := monitoring.GetNamespace("info").GetRegistry() + monitoring.NewString(infoRegistry, "hostname").Set(hostname) // state.host - monitoring.NewFunc(stateRegistry, "host", host.ReportInfo, monitoring.Report) + stateRegistry := monitoring.GetNamespace("state").GetRegistry() + monitoring.NewFunc(stateRegistry, "host", host.ReportInfo(useFQDN), monitoring.Report) } // TestConfig check all settings are ok and the beat can be run @@ -565,9 +582,9 @@ type SetupSettings struct { Dashboard bool Pipeline bool IndexManagement bool - //Deprecated: use IndexManagementKey instead + // Deprecated: use IndexManagementKey instead Template bool - //Deprecated: use IndexManagementKey instead + // Deprecated: use IndexManagementKey instead ILMPolicy bool EnableAllFilesets bool } @@ -709,6 +726,11 @@ func (b *Beat) configure(settings Settings) error { return fmt.Errorf("error unpacking config data: %w", err) } + if err := features.UpdateFromConfig(b.RawConfig); err != nil { + return fmt.Errorf("could not parse features: %w", err) + } + b.RegisterHostname(features.FQDN()) + b.Beat.Config = &b.Config.BeatConfig if name := b.Config.Name; name != "" { diff --git a/libbeat/docs/shared-feature-flags.asciidoc b/libbeat/docs/shared-feature-flags.asciidoc new file mode 100644 index 00000000000..cf53cd626f7 --- /dev/null +++ b/libbeat/docs/shared-feature-flags.asciidoc @@ -0,0 +1,31 @@ +[[configuration-feature-flags]] +== Configure Feature Flags + +++++ +Feature Flags +++++ + +Example configuration with the FQDN feature flag enabled: + +["source","yaml"] +---- +features: + fqdn: + enabled: true +---- + +[float] +=== Configuration options + +You can specify the following options in the `features` section of the +{beatname_lc}.yml+ config file: + +[float] +==== `fqdn` + +Contains configuration for the FQDN reporting feature. When this feature is enabled, {beatname_uc} will +report the fully-qualified domain name for the host on which it's running. + +[float] +===== `enabled` +Set to `true` to enable the FQDN reporting feature of {beatname_uc}. +Defaults to `false`. diff --git a/libbeat/features/features.go b/libbeat/features/features.go new file mode 100644 index 00000000000..997803efad2 --- /dev/null +++ b/libbeat/features/features.go @@ -0,0 +1,133 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package features + +import ( + "fmt" + "sync" + + "github.com/elastic/elastic-agent-client/v7/pkg/proto" + conf "github.com/elastic/elastic-agent-libs/config" +) + +var ( + flags = fflags{} +) + +type boolValueOnChangeCallback func(new, old bool) + +type fflags struct { + mu sync.RWMutex + + // TODO: Refactor to generalize for other feature flags + fqdnEnabled bool + fqdnCallbacks map[string]boolValueOnChangeCallback +} + +// NewConfigFromProto converts the given *proto.Features object to +// a *config.C object. +func NewConfigFromProto(f *proto.Features) (*conf.C, error) { + if f == nil { + return nil, nil + } + + var beatCfg struct { + Features *proto.Features `config:"features"` + } + + beatCfg.Features = f + + c, err := conf.NewConfigFrom(&beatCfg) + if err != nil { + return nil, fmt.Errorf("unable to parse feature flags message into beat configuration: %w", err) + } + + _, err = c.Remove("features.source", -1) + if err != nil { + return nil, fmt.Errorf("unable to convert feature flags message to beat configuration: %w", err) + } + + return c, nil +} + +// UpdateFromConfig updates the feature flags configuration. If c is nil UpdateFromConfig is no-op. +func UpdateFromConfig(c *conf.C) error { + if c == nil { + return nil + } + + type cfg struct { + Features struct { + FQDN *conf.C `json:"fqdn" yaml:"fqdn" config:"fqdn"` + } `json:"features" yaml:"features" config:"features"` + } + + parsedFlags := cfg{} + if err := c.Unpack(&parsedFlags); err != nil { + return fmt.Errorf("could not unpack features config: %w", err) + } + + flags.SetFQDNEnabled(parsedFlags.Features.FQDN.Enabled()) + + return nil +} + +func (f *fflags) SetFQDNEnabled(newValue bool) { + f.mu.Lock() + defer f.mu.Unlock() + + oldValue := f.fqdnEnabled + f.fqdnEnabled = newValue + for _, cb := range f.fqdnCallbacks { + cb(newValue, oldValue) + } +} + +// FQDN reports if FQDN should be used instead of hostname for host.name. +// If it hasn't been set by UpdateFromConfig or UpdateFromProto, it returns false. +func FQDN() bool { + flags.mu.RLock() + defer flags.mu.RUnlock() + return flags.fqdnEnabled +} + +// AddFQDNOnChangeCallback takes a callback function that will be called with the new and old values +// of `flags.fqdnEnabled` whenever it changes. It also takes a string ID - this is useful +// in calling `RemoveFQDNOnChangeCallback` to de-register the callback. +func AddFQDNOnChangeCallback(cb boolValueOnChangeCallback, id string) error { + flags.mu.Lock() + defer flags.mu.Unlock() + + // Initialize callbacks map if necessary. + if flags.fqdnCallbacks == nil { + flags.fqdnCallbacks = map[string]boolValueOnChangeCallback{} + } + + flags.fqdnCallbacks[id] = cb + return nil +} + +// RemoveFQDNOnChangeCallback removes the callback function associated with the given ID (originally +// returned by `AddFQDNOnChangeCallback` so that function will be no longer be called when +// `flags.fqdnEnabled` changes. +func RemoveFQDNOnChangeCallback(id string) { + flags.mu.Lock() + defer flags.mu.Unlock() + + delete(flags.fqdnCallbacks, id) +} diff --git a/libbeat/features/features_test.go b/libbeat/features/features_test.go new file mode 100644 index 00000000000..d4bfe835492 --- /dev/null +++ b/libbeat/features/features_test.go @@ -0,0 +1,188 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package features + +import ( + "testing" + + "google.golang.org/protobuf/types/known/structpb" + + "github.com/elastic/elastic-agent-client/v7/pkg/proto" + "github.com/elastic/elastic-agent-libs/config" + + "github.com/stretchr/testify/require" +) + +func TestNewConfigFromProto(t *testing.T) { + source, err := structpb.NewStruct(map[string]interface{}{ + "fqdn": map[string]interface{}{ + "enabled": false, + }, + }) + require.NoError(t, err) + + tests := map[string]struct { + protoFeatures *proto.Features + expected *config.C + }{ + "nil": { + protoFeatures: nil, + expected: nil, + }, + "fqdn_enabled": { + protoFeatures: &proto.Features{Fqdn: &proto.FQDNFeature{Enabled: true}}, + expected: config.MustNewConfigFrom(` +features: + fqdn: + enabled: true +`), + }, + "fqdn_disabled": { + protoFeatures: &proto.Features{Fqdn: &proto.FQDNFeature{Enabled: false}}, + expected: config.MustNewConfigFrom(` +features: + fqdn: + enabled: false +`), + }, + "with_source": { + protoFeatures: &proto.Features{Fqdn: &proto.FQDNFeature{Enabled: true}, Source: source}, + expected: config.MustNewConfigFrom(` +features: + fqdn: + enabled: true +`), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + c, err := NewConfigFromProto(test.protoFeatures) + require.NoError(t, err) + + require.Equal(t, test.expected, c) + }) + } + +} + +func TestFQDN(t *testing.T) { + tcs := []struct { + name string + yaml string + want bool + }{ + { + name: "FQDN enabled", + yaml: ` + features: + fqdn: + enabled: true`, + want: true, + }, + { + name: "FQDN disabled", + yaml: ` + features: + fqdn: + enabled: false`, + want: false, + }, + { + name: "FQDN only {}", + yaml: ` + features: + fqdn: {}`, + want: true, + }, + { + name: "FQDN empty", + yaml: ` + features: + fqdn:`, + want: false, + }, + { + name: "FQDN absent", + yaml: ` + features:`, + want: false, + }, + { + name: "No features", + yaml: ` + # no features, just a comment`, + want: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + + c, err := config.NewConfigFrom(tc.yaml) + if err != nil { + t.Fatalf("could not parse config YAML: %v", err) + } + + err = UpdateFromConfig(c) + if err != nil { + t.Fatalf("UpdateFromConfig failed: %v", err) + } + + got := FQDN() + if got != tc.want { + t.Errorf("want: %t, got %t", tc.want, got) + } + }) + } +} + +func TestFQDNCallbacks(t *testing.T) { + cb1Called, cb2Called := false, false + + err := AddFQDNOnChangeCallback(func(new, old bool) { + cb1Called = true + }, "cb1") + require.NoError(t, err) + + err = AddFQDNOnChangeCallback(func(new, old bool) { + cb2Called = true + }, "cb2") + require.NoError(t, err) + + defer func() { + // Cleanup in case we don't get to the end of + // this test successfully. + if _, exists := flags.fqdnCallbacks["cb1"]; exists { + RemoveFQDNOnChangeCallback("cb1") + } + if _, exists := flags.fqdnCallbacks["cb2"]; exists { + RemoveFQDNOnChangeCallback("cb2") + } + }() + + require.Len(t, flags.fqdnCallbacks, 2) + flags.SetFQDNEnabled(false) + require.True(t, cb1Called) + require.True(t, cb2Called) + + RemoveFQDNOnChangeCallback("cb1") + require.Len(t, flags.fqdnCallbacks, 1) + RemoveFQDNOnChangeCallback("cb2") + require.Len(t, flags.fqdnCallbacks, 0) +} diff --git a/libbeat/management/management.go b/libbeat/management/management.go index a8eacd45147..fa4f5b89968 100644 --- a/libbeat/management/management.go +++ b/libbeat/management/management.go @@ -119,7 +119,8 @@ type FactoryFunc func(*config.C, *reload.Registry, uuid.UUID) (Manager, error) // Register a config manager func Register(name string, fn PluginFunc, stability feature.Stability) { - f := feature.New(Namespace, name, fn, feature.MakeDetails(name, "", stability)) + f := feature.New( + Namespace, name, fn, feature.MakeDetails(name, "", stability)) feature.MustRegister(f) } diff --git a/libbeat/processors/add_host_metadata/add_host_metadata.go b/libbeat/processors/add_host_metadata/add_host_metadata.go index 5f78c32a84d..6fffe4aa919 100644 --- a/libbeat/processors/add_host_metadata/add_host_metadata.go +++ b/libbeat/processors/add_host_metadata/add_host_metadata.go @@ -22,9 +22,8 @@ import ( "sync" "time" - "github.com/pkg/errors" - "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/features" "github.com/elastic/beats/v7/libbeat/processors" jsprocessor "github.com/elastic/beats/v7/libbeat/processors/script/javascript/module/processor" "github.com/elastic/beats/v7/libbeat/processors/util" @@ -57,30 +56,40 @@ const ( // New constructs a new add_host_metadata processor. func New(cfg *config.C) (processors.Processor, error) { - config := defaultConfig() - if err := cfg.Unpack(&config); err != nil { - return nil, errors.Wrapf(err, "fail to unpack the %v configuration", processorName) + c := defaultConfig() + if err := cfg.Unpack(&c); err != nil { + return nil, fmt.Errorf("fail to unpack the %v configuration: %w", processorName, err) } p := &addHostMetadata{ - config: config, + config: c, data: mapstr.NewPointer(nil), logger: logp.NewLogger("add_host_metadata"), } - p.loadData() + if err := p.loadData(); err != nil { + return nil, fmt.Errorf("failed to load data: %w", err) + } - if config.Geo != nil { - geoFields, err := util.GeoConfigToMap(*config.Geo) + if c.Geo != nil { + geoFields, err := util.GeoConfigToMap(*c.Geo) if err != nil { return nil, err } p.geoData = mapstr.M{"host": mapstr.M{"geo": geoFields}} } + err := features.AddFQDNOnChangeCallback(p.handleFQDNReportingChange, processorName) + if err != nil { + return nil, fmt.Errorf( + "could not register callback for FQDN reporting onChange from %s processor: %w", + processorName, err, + ) + } + return p, nil } -// Run enriches the given event with the host meta data +// Run enriches the given event with the host metadata func (p *addHostMetadata) Run(event *beat.Event) (*beat.Event, error) { // check replace_host_fields field if !p.config.ReplaceFields && skipAddingHostMetadata(event) { @@ -100,6 +109,15 @@ func (p *addHostMetadata) Run(event *beat.Event) (*beat.Event, error) { return event, nil } +// Ideally we'd be able to implement the Closer interface here and +// deregister the callback. But processors that can be used with the +// `script` processor are not allowed to implement the Closer +// interface (@see https://github.com/elastic/beats/pull/16349). +//func (p *addHostMetadata) Close() error { +// features.RemoveFQDNOnChangeCallback(processorName) +// return nil +//} + func (p *addHostMetadata) expired() bool { if p.config.CacheTTL <= 0 { return true @@ -125,7 +143,7 @@ func (p *addHostMetadata) loadData() error { return err } - data := host.MapHostInfo(h.Info()) + data := host.MapHostInfo(features.FQDN(), h.Info()) if p.config.NetInfoEnabled { // IP-address and MAC-address var ipList, hwList, err = util.GetNetInfo() @@ -134,16 +152,23 @@ func (p *addHostMetadata) loadData() error { } if len(ipList) > 0 { - data.Put("host.ip", ipList) + if _, err := data.Put("host.ip", ipList); err != nil { + return fmt.Errorf("could not set host.ip: %w", err) + } } if len(hwList) > 0 { - data.Put("host.mac", hwList) + if _, err := data.Put("host.mac", hwList); err != nil { + return fmt.Errorf("could not set host.mac: %w", err) + } } } if p.config.Name != "" { - data.Put("host.name", p.config.Name) + if _, err := data.Put("host.name", p.config.Name); err != nil { + return fmt.Errorf("could not set host.name: %w", err) + } } + p.data.Set(data) return nil } @@ -153,6 +178,30 @@ func (p *addHostMetadata) String() string { processorName, p.config.NetInfoEnabled, p.config.CacheTTL) } +func (p *addHostMetadata) handleFQDNReportingChange(new, old bool) { + if new == old { + // Nothing to do + return + } + + // Whether we should report the FQDN or not has changed. Expire cache + // so we start report the desired hostname value immediately. + p.expireCache() +} + +func (p *addHostMetadata) expireCache() { + if p.config.CacheTTL <= 0 { + return + } + + p.lastUpdate.Lock() + defer p.lastUpdate.Unlock() + + // Update cache's last updated timestamp to be zero, + // effectively expiring the cache immediately. + p.lastUpdate.Time = time.Time{} +} + func skipAddingHostMetadata(event *beat.Event) bool { // If host fields exist(besides host.name added by libbeat) in event, skip add_host_metadata. hostFields, err := event.Fields.GetValue("host") diff --git a/libbeat/processors/add_host_metadata/add_host_metadata_test.go b/libbeat/processors/add_host_metadata/add_host_metadata_test.go index c0dd7fc8973..44e7584c314 100644 --- a/libbeat/processors/add_host_metadata/add_host_metadata_test.go +++ b/libbeat/processors/add_host_metadata/add_host_metadata_test.go @@ -23,6 +23,8 @@ import ( "testing" "time" + "github.com/elastic/beats/v7/libbeat/features" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -467,3 +469,40 @@ func TestSkipAddingHostMetadata(t *testing.T) { }) } } + +func TestExpireCacheOnFQDNReportingChange(t *testing.T) { + testConfig := conf.MustNewConfigFrom(map[string]interface{}{ + "cache.ttl": "5m", + }) + + p, err := New(testConfig) + require.NoError(t, err) + + ahmP, ok := p.(*addHostMetadata) + require.True(t, ok) + + // Call the expired() method once to prime the cache's + // lastUpdated value + ahmP.expired() + + // Since we just primed the cache's lastUpdated value, the + // cache should no longer be expired. + expired := ahmP.expired() + require.False(t, expired) + + // Toggle the FQDN feature flag; this should cause the cache + // to expire. + features.UpdateFromConfig(conf.MustNewConfigFrom(map[string]interface{}{ + "features.fqdn.enabled": true, + })) + expired = ahmP.expired() + require.True(t, expired) + + // Set the FQDN feature flag to the same value; this should NOT + // cause the cache to expire. + features.UpdateFromConfig(conf.MustNewConfigFrom(map[string]interface{}{ + "features.fqdn.enabled": true, + })) + expired = ahmP.expired() + require.False(t, expired) +} diff --git a/libbeat/publisher/processing/default.go b/libbeat/publisher/processing/default.go index 651edc16859..9b90e61fa35 100644 --- a/libbeat/publisher/processing/default.go +++ b/libbeat/publisher/processing/default.go @@ -23,6 +23,7 @@ import ( "github.com/elastic/beats/v7/libbeat/asset" "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/ecs" + "github.com/elastic/beats/v7/libbeat/features" "github.com/elastic/beats/v7/libbeat/mapping" "github.com/elastic/beats/v7/libbeat/processors" "github.com/elastic/beats/v7/libbeat/processors/actions" @@ -143,10 +144,12 @@ var WithHost modifier = builtinModifier(func(info beat.Info) mapstr.M { // pipeline. func WithAgentMeta() modifier { return builtinModifier(func(info beat.Info) mapstr.M { + hostname := info.FQDNAwareHostname(features.FQDN()) + metadata := mapstr.M{ "ephemeral_id": info.EphemeralID.String(), "id": info.ID.String(), - "name": info.Hostname, + "name": hostname, "type": info.Beat, "version": info.Version, } diff --git a/metricbeat/docs/configuring-howto.asciidoc b/metricbeat/docs/configuring-howto.asciidoc index dcacba01f79..25202cee1a6 100644 --- a/metricbeat/docs/configuring-howto.asciidoc +++ b/metricbeat/docs/configuring-howto.asciidoc @@ -26,6 +26,7 @@ include::{libbeat-dir}/shared/configuring-intro.asciidoc[] * <> * <> * <> +* <> * <<{beatname_lc}-reference-yml>> -- @@ -68,4 +69,6 @@ include::{libbeat-dir}/regexp.asciidoc[] include::{libbeat-dir}/shared-instrumentation.asciidoc[] +include::{libbeat-dir}/shared-feature-flags.asciidoc[] + include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index d04774809f5..597b394d10b 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -2534,3 +2534,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/packetbeat/docs/configuring-howto.asciidoc b/packetbeat/docs/configuring-howto.asciidoc index e389e3c6501..79a59519520 100644 --- a/packetbeat/docs/configuring-howto.asciidoc +++ b/packetbeat/docs/configuring-howto.asciidoc @@ -26,6 +26,7 @@ include::{libbeat-dir}/shared/configuring-intro.asciidoc[] * <> * <> * <> +* <> * <<{beatname_lc}-reference-yml>> -- @@ -60,4 +61,6 @@ include::./protocol-metrics-packetbeat.asciidoc[] include::{libbeat-dir}/shared-instrumentation.asciidoc[] +include::{libbeat-dir}/shared-feature-flags.asciidoc[] + include::{libbeat-dir}/reference-yml.asciidoc[] diff --git a/packetbeat/packetbeat.reference.yml b/packetbeat/packetbeat.reference.yml index 0a2fb775ad3..f650eb2f16e 100644 --- a/packetbeat/packetbeat.reference.yml +++ b/packetbeat/packetbeat.reference.yml @@ -2162,3 +2162,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/winlogbeat/winlogbeat.reference.yml b/winlogbeat/winlogbeat.reference.yml index 24447bf42ed..df02ef8545d 100644 --- a/winlogbeat/winlogbeat.reference.yml +++ b/winlogbeat/winlogbeat.reference.yml @@ -1597,3 +1597,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/auditbeat/auditbeat.reference.yml b/x-pack/auditbeat/auditbeat.reference.yml index 2245d15ee6a..74d9ddd1141 100644 --- a/x-pack/auditbeat/auditbeat.reference.yml +++ b/x-pack/auditbeat/auditbeat.reference.yml @@ -1771,3 +1771,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index fe35d2e21af..57391e3a497 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -5152,3 +5152,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/functionbeat/functionbeat.reference.yml b/x-pack/functionbeat/functionbeat.reference.yml index 43af468e10c..c27af334f7e 100644 --- a/x-pack/functionbeat/functionbeat.reference.yml +++ b/x-pack/functionbeat/functionbeat.reference.yml @@ -1443,3 +1443,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/heartbeat/heartbeat.reference.yml b/x-pack/heartbeat/heartbeat.reference.yml index 9b52eb7fe5d..3c19678c936 100644 --- a/x-pack/heartbeat/heartbeat.reference.yml +++ b/x-pack/heartbeat/heartbeat.reference.yml @@ -1807,3 +1807,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/libbeat/management/generate.go b/x-pack/libbeat/management/generate.go index cc8800b9579..ab80ae43686 100644 --- a/x-pack/libbeat/management/generate.go +++ b/x-pack/libbeat/management/generate.go @@ -42,7 +42,8 @@ func (r *TransformRegister) SetTransform(transform func(*proto.UnitExpectedConfi } // Transform sets a transform function callback -func (r *TransformRegister) Transform(cfg *proto.UnitExpectedConfig, agentInfo *client.AgentInfo) ([]*reload.ConfigWithMeta, error) { +func (r *TransformRegister) Transform( + cfg *proto.UnitExpectedConfig, agentInfo *client.AgentInfo) ([]*reload.ConfigWithMeta, error) { // If no transform is registered, fallback to a basic setup if r.transformFunc == nil { streamList, err := CreateInputsFromStreams(cfg, "log", agentInfo) @@ -182,7 +183,7 @@ func injectIndexStream(dataStreamType string, expected *proto.UnitExpectedConfig // injectStreamProcessors is an emulation of the InjectStreamProcessorRule AST code // this adds a variety of processors for metadata related to the dataset and input config. func injectStreamProcessors(expected *proto.UnitExpectedConfig, dataStreamType string, streamExpected *proto.Stream, stream map[string]interface{}, defaultProcessors []mapstr.M) (map[string]interface{}, error) { - //1. start by "repairing" config to add any missing fields + // 1. start by "repairing" config to add any missing fields // logic from datastreamTypeFromInputNode procInputType, procInputDataset, procInputNamespace := metadataFromDatastreamValues(dataStreamType, expected, streamExpected) @@ -203,7 +204,7 @@ func injectStreamProcessors(expected *proto.UnitExpectedConfig, dataStreamType s processors = append(processors, inputID) } - //2. Actually add the processors + // 2. Actually add the processors // namespace datastream := generateAddFieldsProcessor(mapstr.M{"dataset": procInputDataset, "namespace": procInputNamespace, "type": procInputType}, "data_stream") diff --git a/x-pack/libbeat/management/managerV2.go b/x-pack/libbeat/management/managerV2.go index d9720f03f5a..db73bb8f977 100644 --- a/x-pack/libbeat/management/managerV2.go +++ b/x-pack/libbeat/management/managerV2.go @@ -19,6 +19,7 @@ import ( gproto "google.golang.org/protobuf/proto" "gopkg.in/yaml.v2" + "github.com/elastic/beats/v7/libbeat/features" "github.com/elastic/elastic-agent-client/v7/pkg/client" "github.com/elastic/elastic-agent-client/v7/pkg/proto" conf "github.com/elastic/elastic-agent-libs/config" @@ -81,8 +82,9 @@ type BeatV2Manager struct { lastInputCfgs map[string]*proto.UnitExpectedConfig // used for the debug callback to report as-running config - lastBeatOutputCfg *reload.ConfigWithMeta - lastBeatInputCfgs []*reload.ConfigWithMeta + lastBeatOutputCfg *reload.ConfigWithMeta + lastBeatInputCfgs []*reload.ConfigWithMeta + lastBeatFeaturesCfg *conf.C } // ================================ @@ -172,7 +174,7 @@ func (cm *BeatV2Manager) Enabled() bool { return cm.config.Enabled } -// SetStopCallback sets the callback to run when the manager want to shutdown the beats gracefully. +// SetStopCallback sets the callback to run when the manager want to shut down the beats gracefully. func (cm *BeatV2Manager) SetStopCallback(stopFunc func()) { cm.stopMut.Lock() defer cm.stopMut.Unlock() @@ -188,6 +190,7 @@ func (cm *BeatV2Manager) Start() error { cm.errCanceller() cm.errCanceller = nil } + ctx := context.Background() err := cm.client.Start(ctx) if err != nil { @@ -196,7 +199,13 @@ func (cm *BeatV2Manager) Start() error { ctx, canceller := context.WithCancel(ctx) cm.errCanceller = canceller go cm.watchErrChan(ctx) - cm.client.RegisterDiagnosticHook("beat-rendered-config", "the rendered config used by the beat", "beat-rendered-config.yml", "application/yaml", cm.handleDebugYaml) + cm.client.RegisterDiagnosticHook( + "beat-rendered-config", + "the rendered config used by the beat", + "beat-rendered-config.yml", + "application/yaml", + cm.handleDebugYaml) + go cm.unitListen() cm.isRunning = true return nil @@ -276,8 +285,8 @@ func (cm *BeatV2Manager) updateStatuses() { payload := cm.payload for _, unit := range cm.units { - state, _, _ := unit.Expected() - if state == client.UnitStateStopped { + expected := unit.Expected() + if expected.State == client.UnitStateStopped { // unit is expected to be stopping (don't adjust the state as the state is now managed by the // `reload` method and will be marked stopped in that code path) continue @@ -313,8 +322,13 @@ func (cm *BeatV2Manager) modifyUnit(unit *client.Unit) { cm.mx.Lock() defer cm.mx.Unlock() - state, _, _ := unit.Expected() - if state == client.UnitStateStopped { + // no need to update cm.units because the elastic-agent-client and the beats share + // the pointer to each unit, so when the client updates a unit on its side, it + // is reflected here. As this deals with modifications, they're already present. + // Only the state needs to be updated. + + expected := unit.Expected() + if expected.State == client.UnitStateStopped { // expected to be stopped; needs to stop this unit _ = unit.UpdateState(client.UnitStateStopping, "Stopping", nil) } else { @@ -364,7 +378,7 @@ func (cm *BeatV2Manager) unitListen() { t := time.NewTimer(changeDebounce) t.Stop() // starts stopped, until a change occurs - cm.logger.Debugf("Listening for agent unit changes") + cm.logger.Debug("Listening for agent unit changes") for { select { // The stopChan channel comes from the Manager interface Stop() method @@ -385,8 +399,12 @@ func (cm *BeatV2Manager) unitListen() { cm.UpdateStatus(lbmanagement.Stopping, "Stopping") return case change := <-cm.client.UnitChanges(): + cm.logger.Infof( + "BeatV2Manager.unitListen UnitChanged.Type(%s), UnitChanged.Trigger(%d): %s/%s", + change.Type, int64(change.Triggers), change.Type, change.Triggers) + switch change.Type { - // Within the context of how we send config to beats, I'm not sure there is a difference between + // Within the context of how we send config to beats, I'm not sure if there is a difference between // A unit add and a unit change, since either way we can't do much more than call the reloader case client.UnitChangedAdded: cm.addUnit(change.Unit) @@ -411,7 +429,6 @@ func (cm *BeatV2Manager) unitListen() { cm.mx.Unlock() cm.reload(units) } - } } @@ -443,24 +460,40 @@ func (cm *BeatV2Manager) reload(units map[unitKey]*client.Unit) { var outputUnit *client.Unit var inputUnits []*client.Unit var stoppingUnits []*client.Unit + var errs multierror.Errors + for _, unit := range units { - state, ll, _ := unit.Expected() - if ll > lowestLevel { + expected := unit.Expected() + if expected.LogLevel > lowestLevel { // log level is still used from an expected stopped unit until // the unit is completely removed (aka. fully stopped) - lowestLevel = ll + lowestLevel = expected.LogLevel } - if state == client.UnitStateStopped { + if expected.Features != nil { + // unit is expected to update its feature flags + featuresCfg, err := features.NewConfigFromProto(expected.Features) + if err != nil { + errs = append(errs, err) + } + + if err := features.UpdateFromConfig(featuresCfg); err != nil { + errs = append(errs, err) + } + + cm.lastBeatFeaturesCfg = featuresCfg + } + if expected.State == client.UnitStateStopped { // unit is being stopped // // we keep the unit so after reload is performed // these units can be marked as stopped stoppingUnits = append(stoppingUnits, unit) continue - } else if state != client.UnitStateHealthy { + } else if expected.State != client.UnitStateHealthy { // only stopped or healthy are known (and expected) state // for a unit - cm.logger.Errorf("unit %s has an unknown state %+v", unit.ID(), state) + cm.logger.Errorf("unit %s has an unknown state %+v", + unit.ID(), expected.State) } if unit.Type() == client.UnitTypeOutput { outputUnit = unit @@ -477,7 +510,6 @@ func (cm *BeatV2Manager) reload(units map[unitKey]*client.Unit) { publisher.SetUnderAgentTrace(trace) // reload the output configuration - var errs multierror.Errors if err := cm.reloadOutput(outputUnit); err != nil { errs = append(errs, err) } @@ -508,8 +540,8 @@ func (cm *BeatV2Manager) reload(units map[unitKey]*client.Unit) { payload := cm.payload cm.mx.Unlock() for _, unit := range units { - state, _, _ := unit.Expected() - if state == client.UnitStateStopped { + expected := unit.Expected() + if expected.State == client.UnitStateStopped { // unit is expected to be stopping (don't adjust the state as the state is now managed by the // `reload` method and will be marked stopped in that code path) continue @@ -539,19 +571,19 @@ func (cm *BeatV2Manager) reloadOutput(unit *client.Unit) error { return nil } - _, _, rawConfig := unit.Expected() - if rawConfig == nil { + expected := unit.Expected() + if expected.Config == nil { // should not happen; hard stop return fmt.Errorf("output unit has no config") } - if cm.lastOutputCfg != nil && gproto.Equal(cm.lastOutputCfg, rawConfig) { + if cm.lastOutputCfg != nil && gproto.Equal(cm.lastOutputCfg, expected.Config) { // configuration for the output did not change; do nothing cm.logger.Debug("Skipped reloading output; configuration didn't change") return nil } - cm.logger.Debugf("Got output unit config '%s'", rawConfig.GetId()) + cm.logger.Debugf("Got output unit config '%s'", expected.Config.GetId()) if cm.stopOnOutputReload && cm.lastOutputCfg != nil { cm.logger.Info("beat is restarting because output changed") @@ -560,7 +592,7 @@ func (cm *BeatV2Manager) reloadOutput(unit *client.Unit) error { return nil } - reloadConfig, err := groupByOutputs(rawConfig) + reloadConfig, err := groupByOutputs(expected.Config) if err != nil { return fmt.Errorf("failed to generate config for output: %w", err) } @@ -569,7 +601,7 @@ func (cm *BeatV2Manager) reloadOutput(unit *client.Unit) error { if err != nil { return fmt.Errorf("failed to reload output: %w", err) } - cm.lastOutputCfg = rawConfig + cm.lastOutputCfg = expected.Config cm.lastBeatOutputCfg = reloadConfig return nil } @@ -583,18 +615,19 @@ func (cm *BeatV2Manager) reloadInputs(inputUnits []*client.Unit) error { inputCfgs := make(map[string]*proto.UnitExpectedConfig, len(inputUnits)) inputBeatCfgs := make([]*reload.ConfigWithMeta, 0, len(inputUnits)) agentInfo := cm.client.AgentInfo() + for _, unit := range inputUnits { - _, _, rawConfig := unit.Expected() - if rawConfig == nil { + expected := unit.Expected() + if expected.Config == nil { // should not happen; hard stop return fmt.Errorf("input unit %s has no config", unit.ID()) } - inputCfg, err := generateBeatConfig(rawConfig, agentInfo) + inputCfg, err := generateBeatConfig(expected.Config, agentInfo) if err != nil { return fmt.Errorf("failed to generate configuration for unit %s: %w", unit.ID(), err) } - inputCfgs[unit.ID()] = rawConfig + inputCfgs[unit.ID()] = expected.Config inputBeatCfgs = append(inputBeatCfgs, inputCfg...) } @@ -613,7 +646,7 @@ func (cm *BeatV2Manager) reloadInputs(inputUnits []*client.Unit) error { } // this function is registered as a debug hook -// it prints the last known configuration genreated by the beat +// it prints the last known configuration generated by the beat func (cm *BeatV2Manager) handleDebugYaml() []byte { // generate input inputList := []map[string]interface{}{} @@ -636,15 +669,27 @@ func (cm *BeatV2Manager) handleDebugYaml() []byte { return nil } } - // combine the two in a somewhat coherent way + + // generate features + var featuresCfg map[string]interface{} + if cm.lastBeatFeaturesCfg != nil { + if err := cm.lastBeatFeaturesCfg.Unpack(&featuresCfg); err != nil { + cm.logger.Errorf("error unpacking feature flags config for debug callback: %s", err) + return nil + } + } + + // combine all of the above in a somewhat coherent way // This isn't perfect, but generating a config that can actually be fed back into the beat // would require beatCfg := struct { - Inputs []map[string]interface{} - Outputs map[string]interface{} + Inputs []map[string]interface{} + Outputs map[string]interface{} + Features map[string]interface{} }{ - Inputs: inputList, - Outputs: outputCfg, + Inputs: inputList, + Outputs: outputCfg, + Features: featuresCfg, } data, err := yaml.Marshal(beatCfg) diff --git a/x-pack/libbeat/management/managerV2_test.go b/x-pack/libbeat/management/managerV2_test.go index 192715debb0..952263a43fb 100644 --- a/x-pack/libbeat/management/managerV2_test.go +++ b/x-pack/libbeat/management/managerV2_test.go @@ -21,6 +21,7 @@ import ( "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/beats/v7/libbeat/common/reload" + "github.com/elastic/beats/v7/libbeat/features" ) func TestManagerV2(t *testing.T) { @@ -35,6 +36,7 @@ func TestManagerV2(t *testing.T) { configsSet := false configsCleared := false logLevelSet := false + fqdnEnabled := false allStopped := false onObserved := func(observed *proto.CheckinObserved, currentIdx int) { if currentIdx == 1 { @@ -67,9 +69,12 @@ func TestManagerV2(t *testing.T) { logLevelSet = true t.Logf("debug log level set") } + + fqdnEnabled = features.FQDN() + t.Logf("FQDN feature flag set to %v", fqdnEnabled) } - srv := mockSrvWithUnits([][]*proto.UnitExpected{ + srv := mockSrv([][]*proto.UnitExpected{ { { Id: "output-unit", @@ -180,7 +185,17 @@ func TestManagerV2(t *testing.T) { }, }, {}, - }, onObserved, 500*time.Millisecond) + }, + []uint64{1, 2, 2, 2}, + []*proto.Features{ + nil, + {Fqdn: &proto.FQDNFeature{Enabled: true}}, + nil, + nil, + }, + onObserved, + 500*time.Millisecond, + ) require.NoError(t, srv.Start()) defer srv.Stop() @@ -202,11 +217,17 @@ func TestManagerV2(t *testing.T) { defer m.Stop() require.Eventually(t, func() bool { - return configsSet && configsCleared && logLevelSet && allStopped + return configsSet && configsCleared && logLevelSet && fqdnEnabled && allStopped }, 15*time.Second, 300*time.Millisecond) } -func mockSrvWithUnits(units [][]*proto.UnitExpected, observedCallback func(*proto.CheckinObserved, int), delay time.Duration) *mock.StubServerV2 { +func mockSrv( + units [][]*proto.UnitExpected, + featuresIdxs []uint64, + features []*proto.Features, + observedCallback func(*proto.CheckinObserved, int), + delay time.Duration, +) *mock.StubServerV2 { i := 0 agentInfo := &proto.CheckinAgentInfo{ Id: "elastic-agent-id", @@ -218,27 +239,31 @@ func mockSrvWithUnits(units [][]*proto.UnitExpected, observedCallback func(*prot if observedCallback != nil { observedCallback(observed, i) } - matches := doesStateMatch(observed, units[i]) + matches := doesStateMatch(observed, units[i], featuresIdxs[i]) if !matches { - // send same set of units + // send same set of units and features return &proto.CheckinExpected{ - AgentInfo: agentInfo, - Units: units[i], + AgentInfo: agentInfo, + Units: units[i], + Features: features[i], + FeaturesIdx: featuresIdxs[i], } } // delay sending next expected based on delay if delay > 0 { <-time.After(delay) } - // send next set of units + // send next set of units and features i += 1 if i >= len(units) { // stay on last index i = len(units) - 1 } return &proto.CheckinExpected{ - AgentInfo: agentInfo, - Units: units[i], + AgentInfo: agentInfo, + Units: units[i], + Features: features[i], + FeaturesIdx: featuresIdxs[i], } }, ActionImpl: func(response *proto.ActionResponse) error { @@ -249,12 +274,16 @@ func mockSrvWithUnits(units [][]*proto.UnitExpected, observedCallback func(*prot } } -func doesStateMatch(observed *proto.CheckinObserved, expected []*proto.UnitExpected) bool { - if len(observed.Units) != len(expected) { +func doesStateMatch( + observed *proto.CheckinObserved, + expectedUnits []*proto.UnitExpected, + expectedFeaturesIdx uint64, +) bool { + if len(observed.Units) != len(expectedUnits) { return false } expectedMap := make(map[unitKey]*proto.UnitExpected) - for _, exp := range expected { + for _, exp := range expectedUnits { expectedMap[unitKey{client.UnitType(exp.Type), exp.Id}] = exp } for _, unit := range observed.Units { @@ -266,6 +295,11 @@ func doesStateMatch(observed *proto.CheckinObserved, expected []*proto.UnitExpec return false } } + + if observed.FeaturesIdx != expectedFeaturesIdx { + return false + } + return true } diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 90cd46f423f..27df4614c7f 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -3080,3 +3080,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/osquerybeat/osquerybeat.reference.yml b/x-pack/osquerybeat/osquerybeat.reference.yml index 3e9ded31cc2..fded3615904 100644 --- a/x-pack/osquerybeat/osquerybeat.reference.yml +++ b/x-pack/osquerybeat/osquerybeat.reference.yml @@ -1162,3 +1162,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/packetbeat/packetbeat.reference.yml b/x-pack/packetbeat/packetbeat.reference.yml index 0a2fb775ad3..f650eb2f16e 100644 --- a/x-pack/packetbeat/packetbeat.reference.yml +++ b/x-pack/packetbeat/packetbeat.reference.yml @@ -2162,3 +2162,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true + diff --git a/x-pack/winlogbeat/winlogbeat.reference.yml b/x-pack/winlogbeat/winlogbeat.reference.yml index 01c5c670935..c24827aa6be 100644 --- a/x-pack/winlogbeat/winlogbeat.reference.yml +++ b/x-pack/winlogbeat/winlogbeat.reference.yml @@ -1599,3 +1599,10 @@ logging.files: # This allows to enable 6.7 migration aliases #migration.6_to_7.enabled: false +# =============================== Feature Flags ================================ + +# Enable and configure feature flags. +#features: +# fqdn: +# enabled: true +