diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 61b31810127..ed3a3255765 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -130,7 +130,7 @@ steps: agents: provider: "gcp" # TODO create own image - image: "family/endpoint-windows-10-tester-rel" + image: "family/general-windows-10" machine_type: "n2-standard-8" disk_type: "pd-ssd" retry: @@ -147,7 +147,7 @@ steps: agents: provider: "gcp" # TODO create own image - image: "family/endpoint-windows-11-tester-rel" + image: "family/general-windows-11" machine_type: "n2-standard-8" disk_type: "pd-ssd" retry: @@ -191,6 +191,7 @@ steps: matrix: setup: k8s_version: + - "1.29.0" - "1.28.0" - "1.27.3" - "1.26.6" diff --git a/.gitignore b/.gitignore index b0c8ebec457..3ffafb6f0a5 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ fleet.yml.lock fleet.yml.old pkg/component/fake/component/component pkg/component/fake/shipper/shipper +internal/pkg/agent/install/testblocking/testblocking diff --git a/NOTICE.txt b/NOTICE.txt index 8b353c1a39a..d7916ca01ab 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -3026,11 +3026,11 @@ Contents of probable licence file $GOMODCACHE/github.com/google/pprof@v0.0.0-202 -------------------------------------------------------------------------------- Dependency : github.com/google/uuid -Version: v1.5.0 +Version: v1.6.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/google/uuid@v1.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/google/uuid@v1.6.0/LICENSE: Copyright (c) 2009,2014 Google Inc. All rights reserved. @@ -4417,11 +4417,11 @@ THE SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/mitchellh/mapstructure -Version: v1.5.1-0.20220423185008-bf980b35cac4 +Version: v1.5.1-0.20231216201459-8508981c8b6c Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/mapstructure@v1.5.1-0.20220423185008-bf980b35cac4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/mapstructure@v1.5.1-0.20231216201459-8508981c8b6c/LICENSE: The MIT License (MIT) @@ -4659,11 +4659,11 @@ Contents of probable licence file $GOMODCACHE/github.com/oklog/ulid@v1.3.1/LICEN -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -4870,11 +4870,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5081,11 +5081,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5292,11 +5292,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5503,11 +5503,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -7265,11 +7265,11 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/go-licence-detector@ -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/component -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/component@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/component@v0.93.0/LICENSE: Apache License @@ -7477,11 +7477,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/comp -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/confmap -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/confmap@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/confmap@v0.93.0/LICENSE: Apache License @@ -7689,11 +7689,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/exporter -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter@v0.93.0/LICENSE: Apache License @@ -7901,11 +7901,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/expo -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/exporter/debugexporter -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter/debugexporter@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter/debugexporter@v0.93.0/LICENSE: Apache License @@ -8113,11 +8113,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/expo -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/exporter/otlpexporter -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter/otlpexporter@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exporter/otlpexporter@v0.93.0/LICENSE: Apache License @@ -8325,11 +8325,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/expo -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/otelcol -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/otelcol@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/otelcol@v0.93.0/LICENSE: Apache License @@ -8537,11 +8537,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/otel -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/processor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor@v0.93.0/LICENSE: Apache License @@ -8749,11 +8749,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/proc -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/processor/batchprocessor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor/batchprocessor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor/batchprocessor@v0.93.0/LICENSE: Apache License @@ -8961,11 +8961,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/proc -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/processor/memorylimiterprocessor -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor/memorylimiterprocessor@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/processor/memorylimiterprocessor@v0.93.0/LICENSE: Apache License @@ -9173,11 +9173,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/proc -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/receiver -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/receiver@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/receiver@v0.93.0/LICENSE: Apache License @@ -9385,11 +9385,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/rece -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/receiver/otlpreceiver -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/receiver/otlpreceiver@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/receiver/otlpreceiver@v0.93.0/LICENSE: Apache License @@ -15288,11 +15288,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/go-logr/logr -Version: v1.3.0 +Version: v1.4.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v1.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/go-logr/logr@v1.4.1/LICENSE: Apache License Version 2.0, January 2004 @@ -20691,217 +20691,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/matttproud/golang_protobuf_extensions/v2 -Version: v2.0.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/matttproud/golang_protobuf_extensions/v2@v2.0.0/LICENSE: - - Apache License - Version 2.0, January 2004 - http://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 - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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 - - 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. - - -------------------------------------------------------------------------------- Dependency : github.com/mitchellh/colorstring Version: v0.0.0-20190213212951-d06e56a500db @@ -22269,11 +22058,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -22480,11 +22269,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/internal/common -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/common@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/common@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -22691,11 +22480,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -22902,11 +22691,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23113,11 +22902,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23324,11 +23113,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23535,11 +23324,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23746,11 +23535,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23957,11 +23746,11 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza@v0.93.0/LICENSE: Apache License Version 2.0, January 2004 @@ -25080,11 +24869,11 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model -------------------------------------------------------------------------------- Dependency : github.com/prometheus/common -Version: v0.45.0 +Version: v0.46.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.45.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.46.0/LICENSE: Apache License Version 2.0, January 2004 @@ -27195,6 +26984,38 @@ Contents of probable licence file $GOMODCACHE/github.com/tklauser/numcpus@v0.6.1 limitations under the License. +-------------------------------------------------------------------------------- +Dependency : github.com/valyala/fastjson +Version: v1.6.4 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/valyala/fastjson@v1.6.4/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2018 Aliaksandr Valialkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER 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/youmark/pkcs8 Version: v0.0.0-20201027041543-1326539a0a0a @@ -28134,11 +27955,11 @@ Contents of probable licence file $GOMODCACHE/go.opencensus.io@v0.24.0/LICENSE: -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector@v0.93.0/LICENSE: Apache License @@ -28346,11 +28167,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector@v0.9 -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configauth -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configauth@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configauth@v0.93.0/LICENSE: Apache License @@ -28558,11 +28379,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configcompression -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configcompression@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configcompression@v0.93.0/LICENSE: Apache License @@ -28770,11 +28591,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configgrpc -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configgrpc@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configgrpc@v0.93.0/LICENSE: Apache License @@ -28982,11 +28803,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/confighttp -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/confighttp@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/confighttp@v0.93.0/LICENSE: Apache License @@ -29194,11 +29015,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/confignet -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/confignet@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/confignet@v0.93.0/LICENSE: Apache License @@ -29406,11 +29227,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configopaque -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configopaque@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configopaque@v0.93.0/LICENSE: Apache License @@ -29618,11 +29439,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configretry -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configretry@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configretry@v0.93.0/LICENSE: Apache License @@ -29830,11 +29651,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configtelemetry -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configtelemetry@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configtelemetry@v0.93.0/LICENSE: Apache License @@ -30042,11 +29863,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/configtls -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configtls@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/configtls@v0.93.0/LICENSE: Apache License @@ -30254,11 +30075,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/config/internal -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/internal@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/config/internal@v0.93.0/LICENSE: Apache License @@ -30466,11 +30287,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conf -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/connector -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/connector@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/connector@v0.93.0/LICENSE: Apache License @@ -30678,11 +30499,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/conn -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/consumer -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/consumer@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/consumer@v0.93.0/LICENSE: Apache License @@ -30890,11 +30711,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/cons -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/extension -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension@v0.93.0/LICENSE: Apache License @@ -31102,11 +30923,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exte -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/extension/auth -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension/auth@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension/auth@v0.93.0/LICENSE: Apache License @@ -31314,11 +31135,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/exte -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/extension/zpagesextension -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension/zpagesextension@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/extension/zpagesextension@v0.93.0/LICENSE: Apache License @@ -31950,11 +31771,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/pdat -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/semconv -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semconv@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semconv@v0.93.0/LICENSE: Apache License @@ -32162,11 +31983,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semc -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/collector/service -Version: v0.92.0 +Version: v0.93.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/service@v0.92.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/service@v0.93.0/LICENSE: Apache License @@ -32585,11 +32406,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib@v0.20. -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/contrib/config -Version: v0.1.1 +Version: v0.2.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/config@v0.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/config@v0.2.0/LICENSE: Apache License Version 2.0, January 2004 @@ -32796,11 +32617,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/config -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc -Version: v0.46.1 +Version: v0.47.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.46.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.47.0/LICENSE: Apache License Version 2.0, January 2004 @@ -33007,11 +32828,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instru -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp -Version: v0.46.1 +Version: v0.47.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.46.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.47.0/LICENSE: Apache License Version 2.0, January 2004 @@ -33218,11 +33039,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/instru -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/contrib/propagators/b3 -Version: v1.21.1 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/propagators/b3@v1.21.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/propagators/b3@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -33429,11 +33250,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/propag -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/contrib/zpages -Version: v0.46.1 +Version: v0.47.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/zpages@v0.46.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/zpages@v0.47.0/LICENSE: Apache License Version 2.0, January 2004 @@ -33640,11 +33461,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/contrib/zpages -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -33851,11 +33672,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.21.0/L -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/bridge/opencensus -Version: v0.44.0 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/bridge/opencensus@v0.44.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/bridge/opencensus@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 @@ -34062,11 +33883,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/bridge/op -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc -Version: v0.44.0 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc@v0.44.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 @@ -34273,11 +34094,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp -Version: v0.44.0 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp@v0.44.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 @@ -34484,11 +34305,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/otlp/otlptrace -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -34695,11 +34516,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -34906,11 +34727,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -35117,11 +34938,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/prometheus -Version: v0.44.1-0.20231201153405-6027c1ae76f2 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/prometheus@v0.44.1-0.20231201153405-6027c1ae76f2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/prometheus@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 @@ -35328,11 +35149,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/stdout/stdoutmetric -Version: v0.44.0 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric@v0.44.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 @@ -35539,11 +35360,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/exporters/stdout/stdouttrace -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/stdout/stdouttrace@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters/stdout/stdouttrace@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -35750,11 +35571,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/exporters -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/metric -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -35961,11 +35782,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1 -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/sdk -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -36172,11 +35993,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.21 -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/sdk/metric -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -36383,11 +36204,11 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metri -------------------------------------------------------------------------------- Dependency : go.opentelemetry.io/otel/trace -Version: v1.21.0 +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.21.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.22.0/LICENSE: Apache License Version 2.0, January 2004 @@ -36939,11 +36760,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : golang.org/x/oauth2 -Version: v0.13.0 +Version: v0.16.0 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/golang.org/x/oauth2@v0.13.0/LICENSE: +Contents of probable licence file $GOMODCACHE/golang.org/x/oauth2@v0.16.0/LICENSE: Copyright (c) 2009 The Go Authors. All rights reserved. diff --git a/changelog/fragments/1704824761-fleet-config-change-logging.yaml b/changelog/fragments/1704824761-fleet-config-change-logging.yaml new file mode 100644 index 00000000000..94a47aa7b67 --- /dev/null +++ b/changelog/fragments/1704824761-fleet-config-change-logging.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: feature + +# Change summary; a 80ish characters long description of the change. +summary: fleet-config-change-logging + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +#description: + +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: Coordinator + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +#pr: https://github.com/owner/repo/1234 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +#issue: https://github.com/owner/repo/1234 diff --git a/changelog/fragments/1704994055-add-error-statements.yaml b/changelog/fragments/1704994055-add-error-statements.yaml new file mode 100644 index 00000000000..0be47eb9359 --- /dev/null +++ b/changelog/fragments/1704994055-add-error-statements.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: enhancement + +# Change summary; a 80ish characters long description of the change. +summary: add error descriptors to inspect command, config methods + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +#description: + +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: config + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +#pr: https://github.com/owner/repo/1234 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +#issue: https://github.com/owner/repo/1234 diff --git a/changelog/fragments/1706123313-on-Windows-prevent-uninstall-from-within-installed-directory.yaml b/changelog/fragments/1706123313-on-Windows-prevent-uninstall-from-within-installed-directory.yaml new file mode 100644 index 00000000000..5f4673be326 --- /dev/null +++ b/changelog/fragments/1706123313-on-Windows-prevent-uninstall-from-within-installed-directory.yaml @@ -0,0 +1,32 @@ +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: bug-fix + +# Change summary; a 80ish characters long description of the change. +summary: On Windows prevent uninstall from within installed directory + +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment. +description: 'On Windows, prevent uninstall from within installed directory to prevent a sharing violation. Also for install and uninstall, print debug logs to stderr if command fails.' + +# Affected component; a word indicating the component this changeset affects. +component: agent + +# PR URL; optional; the PR number that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +#pr: https://github.com/owner/repo/1234 + +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +#issue: https://github.com/owner/repo/1234 diff --git a/dev-tools/cmd/buildfleetcfg/buildfleetcfg.go b/dev-tools/cmd/buildfleetcfg/buildfleetcfg.go index df35609de01..b0c93073bc9 100644 --- a/dev-tools/cmd/buildfleetcfg/buildfleetcfg.go +++ b/dev-tools/cmd/buildfleetcfg/buildfleetcfg.go @@ -9,7 +9,6 @@ import ( "flag" "fmt" "go/format" - "io/ioutil" "os" "text/template" @@ -84,7 +83,7 @@ func main() { return } - ioutil.WriteFile(output, data, 0640) + os.WriteFile(output, data, 0640) return } diff --git a/dev-tools/licenses/license_generate.go b/dev-tools/licenses/license_generate.go index e451cddb356..dc5ec58f8ba 100644 --- a/dev-tools/licenses/license_generate.go +++ b/dev-tools/licenses/license_generate.go @@ -8,7 +8,6 @@ import ( "bytes" "flag" "go/format" - "io/ioutil" "os" "text/template" ) @@ -52,13 +51,13 @@ func init() { func main() { Headers := make(map[string]string) - content, err := ioutil.ReadFile("ELASTIC-LICENSE-header.txt") + content, err := os.ReadFile("ELASTIC-LICENSE-header.txt") if err != nil { panic("could not read Elastic license.") } Headers["Elastic"] = string(content) - content, err = ioutil.ReadFile("ELASTIC-LICENSE-2.0-header.txt") + content, err = os.ReadFile("ELASTIC-LICENSE-2.0-header.txt") if err != nil { panic("could not read Elastic License 2.0 license.") } @@ -78,6 +77,6 @@ func main() { if output == "-" { os.Stdout.Write(bs) } else { - ioutil.WriteFile(output, bs, 0640) + os.WriteFile(output, bs, 0640) } } diff --git a/dev-tools/mage/common.go b/dev-tools/mage/common.go index 80108357b89..724aea784bb 100644 --- a/dev-tools/mage/common.go +++ b/dev-tools/mage/common.go @@ -19,7 +19,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "net/http" "os" @@ -118,7 +117,7 @@ func joinMaps(args ...map[string]interface{}) map[string]interface{} { } func expandFile(src, dst string, args ...map[string]interface{}) error { - tmplData, err := ioutil.ReadFile(src) + tmplData, err := os.ReadFile(src) if err != nil { return fmt.Errorf("failed reading from template %v, %w", src, err) } @@ -133,7 +132,7 @@ func expandFile(src, dst string, args ...map[string]interface{}) error { return err } - if err = ioutil.WriteFile(createDir(dst), []byte(output), 0644); err != nil { + if err = os.WriteFile(createDir(dst), []byte(output), 0644); err != nil { return fmt.Errorf("failed to write rendered template: %w", err) } @@ -236,13 +235,13 @@ func FindReplace(file string, re *regexp.Regexp, repl string) error { return err } - contents, err := ioutil.ReadFile(file) + contents, err := os.ReadFile(file) if err != nil { return err } out := re.ReplaceAllString(string(contents), repl) - return ioutil.WriteFile(file, []byte(out), info.Mode().Perm()) + return os.WriteFile(file, []byte(out), info.Mode().Perm()) } // MustFindReplace invokes FindReplace and panics if an error occurs. @@ -481,6 +480,14 @@ func untar(sourceFile, destinationDir string) error { if err = writer.Close(); err != nil { return err } + case tar.TypeSymlink: + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + if err := os.Symlink(header.Linkname, path); err != nil { + return fmt.Errorf("error creating symlink %s pointing to %s: %w", path, header.Linkname, err) + } + default: return fmt.Errorf("unable to untar type=%c in file=%s", header.Typeflag, path) } @@ -862,21 +869,21 @@ var parseVersionRegex = regexp.MustCompile(`(?m)^[^\d]*(?P\d+)\.(?P + {{ manifest }} # MacOS pkg spec for community beats. - &macos_agent_pkg_spec @@ -159,6 +163,10 @@ shared: content: > {{ commit }} mode: 0644 + 'manifest.yaml': + mode: 0644 + content: > + {{ manifest }} - &agent_binary_files '{{.BeatName}}{{.BinaryExt}}': diff --git a/go.mod b/go.mod index 74fe7d209ed..a47a07b1128 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/gofrs/uuid v4.4.0+incompatible github.com/google/go-cmp v0.6.0 github.com/google/pprof v0.0.0-20230426061923-93006964c1fc - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 @@ -39,13 +39,13 @@ require ( github.com/magefile/mage v1.15.0 github.com/mitchellh/gox v1.0.1 github.com/mitchellh/hashstructure v1.1.0 - github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 + github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c github.com/oklog/ulid v1.3.1 - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.92.0 - github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.92.0 - github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.92.0 - github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.92.0 - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.92.0 + github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.93.0 + github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.93.0 + github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.93.0 + github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.93.0 + github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.93.0 github.com/otiai10/copy v1.14.0 github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0 github.com/pkg/errors v0.9.1 @@ -59,17 +59,17 @@ require ( go.elastic.co/apm/module/apmgorilla v1.15.0 go.elastic.co/ecszap v1.0.1 go.elastic.co/go-licence-detector v0.5.0 - go.opentelemetry.io/collector/component v0.92.0 - go.opentelemetry.io/collector/confmap v0.92.0 - go.opentelemetry.io/collector/exporter v0.92.0 - go.opentelemetry.io/collector/exporter/debugexporter v0.92.0 - go.opentelemetry.io/collector/exporter/otlpexporter v0.92.0 - go.opentelemetry.io/collector/otelcol v0.92.0 - go.opentelemetry.io/collector/processor v0.92.0 - go.opentelemetry.io/collector/processor/batchprocessor v0.92.0 - go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.92.0 - go.opentelemetry.io/collector/receiver v0.92.0 - go.opentelemetry.io/collector/receiver/otlpreceiver v0.92.0 + go.opentelemetry.io/collector/component v0.93.0 + go.opentelemetry.io/collector/confmap v0.93.0 + go.opentelemetry.io/collector/exporter v0.93.0 + go.opentelemetry.io/collector/exporter/debugexporter v0.93.0 + go.opentelemetry.io/collector/exporter/otlpexporter v0.93.0 + go.opentelemetry.io/collector/otelcol v0.93.0 + go.opentelemetry.io/collector/processor v0.93.0 + go.opentelemetry.io/collector/processor/batchprocessor v0.93.0 + go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.93.0 + go.opentelemetry.io/collector/receiver v0.93.0 + go.opentelemetry.io/collector/receiver/otlpreceiver v0.93.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.18.0 golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc @@ -95,7 +95,6 @@ require ( ) require ( - contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect github.com/Jeffail/gabs/v2 v2.6.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/akavel/rsrc v0.8.0 // indirect @@ -119,9 +118,7 @@ require ( github.com/expr-lang/expr v1.15.8 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect @@ -159,7 +156,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -171,21 +167,20 @@ require ( github.com/mostynb/go-grpc-compression v1.2.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo/v2 v2.9.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.92.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.92.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.92.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.92.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.92.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.92.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.93.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.93.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.46.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rs/cors v1.10.1 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect @@ -196,6 +191,7 @@ require ( github.com/stretchr/objx v0.5.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect + github.com/valyala/fastjson v1.6.4 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.elastic.co/apm/module/apmhttp v1.15.0 // indirect @@ -203,48 +199,48 @@ require ( go.elastic.co/apm/v2 v2.0.0 // indirect go.elastic.co/fastjson v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/collector v0.92.0 // indirect - go.opentelemetry.io/collector/config/configauth v0.92.0 // indirect - go.opentelemetry.io/collector/config/configcompression v0.92.0 // indirect - go.opentelemetry.io/collector/config/configgrpc v0.92.0 // indirect - go.opentelemetry.io/collector/config/confighttp v0.92.0 // indirect - go.opentelemetry.io/collector/config/confignet v0.92.0 // indirect - go.opentelemetry.io/collector/config/configopaque v0.92.0 // indirect - go.opentelemetry.io/collector/config/configretry v0.92.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.92.0 // indirect - go.opentelemetry.io/collector/config/configtls v0.92.0 // indirect - go.opentelemetry.io/collector/config/internal v0.92.0 // indirect - go.opentelemetry.io/collector/connector v0.92.0 // indirect - go.opentelemetry.io/collector/consumer v0.92.0 // indirect - go.opentelemetry.io/collector/extension v0.92.0 // indirect - go.opentelemetry.io/collector/extension/auth v0.92.0 // indirect + go.opentelemetry.io/collector v0.93.0 // indirect + go.opentelemetry.io/collector/config/configauth v0.93.0 // indirect + go.opentelemetry.io/collector/config/configcompression v0.93.0 // indirect + go.opentelemetry.io/collector/config/configgrpc v0.93.0 // indirect + go.opentelemetry.io/collector/config/confighttp v0.93.0 // indirect + go.opentelemetry.io/collector/config/confignet v0.93.0 // indirect + go.opentelemetry.io/collector/config/configopaque v0.93.0 // indirect + go.opentelemetry.io/collector/config/configretry v0.93.0 // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.93.0 // indirect + go.opentelemetry.io/collector/config/configtls v0.93.0 // indirect + go.opentelemetry.io/collector/config/internal v0.93.0 // indirect + go.opentelemetry.io/collector/connector v0.93.0 // indirect + go.opentelemetry.io/collector/consumer v0.93.0 // indirect + go.opentelemetry.io/collector/extension v0.93.0 // indirect + go.opentelemetry.io/collector/extension/auth v0.93.0 // indirect go.opentelemetry.io/collector/featuregate v1.0.1 // indirect go.opentelemetry.io/collector/pdata v1.0.1 // indirect - go.opentelemetry.io/collector/semconv v0.92.0 // indirect - go.opentelemetry.io/collector/service v0.92.0 // indirect - go.opentelemetry.io/contrib/config v0.1.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect - go.opentelemetry.io/otel/bridge/opencensus v0.44.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.44.1-0.20231201153405-6027c1ae76f2 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.44.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/collector/semconv v0.93.0 // indirect + go.opentelemetry.io/collector/service v0.93.0 // indirect + go.opentelemetry.io/contrib/config v0.2.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.22.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/bridge/opencensus v0.45.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.45.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.45.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.45.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.45.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/sdk v1.22.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect diff --git a/go.sum b/go.sum index edf12efbe9f..6694452f4cb 100644 --- a/go.sum +++ b/go.sum @@ -485,7 +485,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -927,8 +926,8 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= @@ -1108,8 +1107,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -1393,8 +1392,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -1431,8 +1428,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= -github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -1528,34 +1525,34 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.27.3 h1:5VwIwnBY3vbBDOJrNtA4rVdiTZCsq9B5F12pvy1Drmk= github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.92.0 h1:R9p0RcxnDrkoYjuITbtVAgUeVzJ9+7b1xGdEF9DZDbA= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.92.0/go.mod h1:H12xn4sBQaRtvqYdAb0HL8WrtrP4hcgdVjgAbNE/6BU= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.92.0 h1:0GynhCiPiT3qS8LDTr3vHV9UCCdlr9H1HHi610ISZyo= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.92.0/go.mod h1:SAjAeh25eZIPi1TK7KIZ2hpwSNRhoQVnwjsM6B2mu3w= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.92.0 h1:x36ZvOy+ad363p3viPF2FZnaxcM2yoUPQpg9VX89unw= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.92.0/go.mod h1:qELp3+4I6DZUAbv5S3oyzxKGZHhwC82A0oOutosMtYg= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.92.0 h1:1UF2MF9boARNt/3L9SExlIMggp8htU4OiPz050CS6SM= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.92.0/go.mod h1:MwTANoi8W1PxCOR3VcRNjPvoDpCLe98tzjFTU55jXhQ= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.92.0 h1:8ULgM2gWQYl9jq5uX2KqtQPFeBIM4TufAL91fFG2e5g= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.92.0/go.mod h1:AOTtYRG7j3hw/yPnul76yBNTN52bzUX1XigKS7c5+HI= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.92.0 h1:jG9K/J2UtjlsTnQaQZHyDB2uOD1ZMhzf39Ko3fwHJsw= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.92.0/go.mod h1:OhiKMy/kHVp8Lfm6a75axDwtoU+1xEAWjT8qOxtuioM= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.92.0 h1:hYDw9amC8zJl9uik4zkaPqPHogZ7PMhoY5qaBwMSRQ4= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.92.0/go.mod h1:6V4eg/9WNeiAJ1bqUyHE7t5wP03L/1ecB1dRk7jWm0Q= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.92.0 h1:2cjUFC0jNSqAYcO+ZWUQ8sqPZdAX03Bd90SpsGcnrNY= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.92.0/go.mod h1:SOBg+bs2hOmckkRr/yURA78AuMePwRYIpao4EmI6xdw= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.92.0 h1:sqs1y0Exyxons2mWMAmBSdcdl2UizUgOmoibEBRX/4I= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.92.0/go.mod h1:me0dUlXvkVpDA6bN2z+qAggsXqOBEcm/dFFPw2mp7n8= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.92.0 h1:HpZYkjb3z9DSF79iAw/NAa4/2H2qqWWqYudJ25P4A/g= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.92.0/go.mod h1:csRtnY1VNPVO82nxvGuH5s+4iVbxb9jLIuCSnUp5vwQ= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.92.0 h1:H7mtRBrLtCKqmA4RTrAOxvnvzKUU5KEr4dQvORkmrGc= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.92.0/go.mod h1:feJBCo8tq/NFlHfL5eG+88QdaoZwyj/C9HLxg0C8b6M= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.92.0 h1:L+pCvFFY1sFLQI8bzLsjpj3jbk/vu/URan7jL0tY+m0= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.92.0/go.mod h1:XuEsoBYYtIvJghTAZcuL5cS/k6kKBpJhPCZukUfsUDY= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.92.0 h1:5MFfqmUWCpQpuxlUeN3wOROeL4F2HtmhAJvJPVf+66E= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.92.0/go.mod h1:ls/06DNIHU6YEesJk1qpCABrmD/yZe99BvfOY4yKTKQ= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.92.0 h1:rYpAvfIurB6zjjl1CzmaDtj6br1HT8taGed3IwDmdoY= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.92.0/go.mod h1:4PiIhpYsRDxFHHtuGP3JbA7NfXfSN6owqKCfPG17/30= +github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.93.0 h1:4x8CykpOewhdh8DBatsYBqnUjz1NjzJZ/6t9NkDIPSo= +github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.93.0/go.mod h1:azByt/5p+xzQpi9b/CoB6gxzZe5KwR/07BPmSAaVj0k= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.93.0 h1:Ffq1pCM1BNzLSOZETYRkiJV7TlOBF10s0PsNBHnrDn0= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.93.0/go.mod h1:rUBNp/JzzLWpKNb7DHTvJ5kZKA1chPWc3Hc/V4DWnqk= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.93.0 h1:l2tQFbMQWLEYPiXFWPEhhCRwLDtJuC8o+wll2jNeKXc= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.93.0/go.mod h1:paPB+PvAyGZuxLSUBawTPpu0Cbw6tUa/mleY/OUun38= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.93.0 h1:Ei+8BMFhMb6jkZhZoz6w6LG0wb+APZ1xxTfYTtCYlr4= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.93.0/go.mod h1:1xxL5U1cpBaAY9r14z06qX55YEVZSglq9xv1JKZdODw= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.93.0 h1:2GSwoWsGd99gOzLW24q2RUg07uPzvUCZ0PGDbNXO/88= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.93.0/go.mod h1:tNlfP3YZXf+7Kj/gevpUy/xFJR8uf2/RzWBwxAclLug= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.93.0 h1:qsu9lDUWwwGA+73JpLVECROE8uQZQj99AN7m+F/iXiw= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.93.0/go.mod h1:wEv4N8NtUTUWTYd8z5K0VBI/DiBVk2bO33EqNxsylcE= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.93.0 h1:cAHnEwoS5076UjEXT2rnYq7kcCnhYyVjB6dez00nxWM= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.93.0/go.mod h1:CPe0mhak+OD+pujrNxRNI/fxF5mOnVmv87aSjouB5D8= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.93.0 h1:R0GGB09OWAP1bSVps2brDOOln8pgSgzHU658bdzIb+g= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.93.0/go.mod h1:7SXQW+a9kZ1T1WH9tKwFqfGGefGv8mZxRG/lTsa65uo= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.93.0 h1:2AKT1xw2KNenv/nfRoWueYxQiLJe76Axhb5++4jdgiA= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.93.0/go.mod h1:VmP4/AOAPwtpAG4TYHtWha603iLbLRmO7k0d0WbRqrM= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.93.0 h1:4CQnh6M2vR1j4jcw7m0q4dsdQUQ9wfE0Gdsm8vFmu60= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.93.0/go.mod h1:c4O1ckz309eAPjY2B7ea6SM2WmERcptM8yGpBfoyPQw= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.93.0 h1:01oax6zyX4hdjXgGf2tPS7B+3cNedGBbXn0SvUh9UWE= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.93.0/go.mod h1:KnnM8ZRrnw/qnZdbSvjthAiQJ1EEZsiETK8oRZwvOSQ= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.93.0 h1:0Or54ATMcceixFRnLi21pFa9jwplSME2e2PmlG6vNDg= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.93.0/go.mod h1:JEy+5w/IT2FElPBMx+NVd2Ph7V8UMoSk57HWZsbthvA= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.93.0 h1:o3H1wxCXp3aAmwUFv/xnWMPYXuwxPUp+iY6OhYwWdOE= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.93.0/go.mod h1:BLowm9AexnAogSAdjtICLAteyPWxCQhiBklSCBzC5z4= +github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.93.0 h1:Uzc3Nry6Uent4+2mj4USdiz71/REw57zTytl2zxl4bU= +github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.93.0/go.mod h1:uyfSV+eVY1LeC6V7jKmQs9RlaIz6lHcX2VOR2f27zqU= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1638,8 +1635,6 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= @@ -1661,10 +1656,9 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= +github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1812,7 +1806,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1842,6 +1835,8 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= +github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -1940,143 +1935,143 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector v0.92.0 h1:XiC0ptaT1EmOkK2RI0gt3n2tkzLAkNQGf0E7hrGdyeA= -go.opentelemetry.io/collector v0.92.0/go.mod h1:wbksjM63DTKA1BbdUVS7gAFzAngCZTWb46RBpKdtsPw= -go.opentelemetry.io/collector/component v0.92.0 h1:/tRgPT1hr4KNB8ABHa0oJsjJFRZ5oiCIYHcTpZGwm9s= -go.opentelemetry.io/collector/component v0.92.0/go.mod h1:C2JwPTjauu36UCAzwX71/glNnOc5BR18p8FVccCFsqc= -go.opentelemetry.io/collector/config/configauth v0.92.0 h1:m4O5QLerdsuWYEV8bZGZWDHnM8TtHkr52q9r6hAkasw= -go.opentelemetry.io/collector/config/configauth v0.92.0/go.mod h1:P3tCzSFgxxmBdELVA/h05fGjyYXOr6mCDG4995yPzqo= -go.opentelemetry.io/collector/config/configcompression v0.92.0 h1:LtHx4ZkW3BMxa4CfQGMOE7+ZhXvd4W10Pxa91Hr8IL0= -go.opentelemetry.io/collector/config/configcompression v0.92.0/go.mod h1:fA36AZC/Qcyl+HvMnvFZuV/iUWGQJrchimmk+qYWuMM= -go.opentelemetry.io/collector/config/configgrpc v0.92.0 h1:vXUlGdAfg8ZvzkCyYx5+eagbzj2cQK306C3tZpWb7hY= -go.opentelemetry.io/collector/config/configgrpc v0.92.0/go.mod h1:MOUXJ4rVhsYQ+1nv8AxuwuFNWeCWrWRnjo2aP+5zRh0= -go.opentelemetry.io/collector/config/confighttp v0.92.0 h1:O1iAgwVJBnHgLqzHMBBbI0pa0nBZHalTQrFQGwiEuiE= -go.opentelemetry.io/collector/config/confighttp v0.92.0/go.mod h1:ZnZz2+bIHk4PRnJMvSPjQWdTDkfoBb4cH2R2gQVf1V4= -go.opentelemetry.io/collector/config/confignet v0.92.0 h1:4B4Ir68P+ew3nVz2/9lBN+KGXtkETPqErM8nQCg8tFo= -go.opentelemetry.io/collector/config/confignet v0.92.0/go.mod h1:rraribsOoZsYZm51+3TXHavmXKJOC5a5/X20vfmNbdw= -go.opentelemetry.io/collector/config/configopaque v0.92.0 h1:YvUSVa3Vxt2gSl5SwEohtn9HG0+8bO4zuAOCVICBIVU= -go.opentelemetry.io/collector/config/configopaque v0.92.0/go.mod h1:dQK8eUXjIGKaw1RB7UIg2nqx56AueNxeKFCdB0P1ypg= -go.opentelemetry.io/collector/config/configretry v0.92.0 h1:3WUabmCRIBHSkOLGCHGieUGchlHkBw3Fa4Cj9Do5Xdw= -go.opentelemetry.io/collector/config/configretry v0.92.0/go.mod h1:gt1HRYyMxcMca9lbDLPbivQzsUCjVjkPAn/3S6fiD14= -go.opentelemetry.io/collector/config/configtelemetry v0.92.0 h1:iCfxJ2DhWVOAHpGgkWUZRfUvUPyWGhpVRCqjPQ2D87Y= -go.opentelemetry.io/collector/config/configtelemetry v0.92.0/go.mod h1:2XLhyR/GVpWeZ2K044vCmrvH/d4Ewt0aD/y46avZyMU= -go.opentelemetry.io/collector/config/configtls v0.92.0 h1:jJHZvRp8CZ76IYbhHdGgGosBMQ/EShQAc0NlE3/tlHk= -go.opentelemetry.io/collector/config/configtls v0.92.0/go.mod h1:rL9BH5Hyrkni4t+QOx/opuwD0CHq/ZIFTsh6QLLsbmA= -go.opentelemetry.io/collector/config/internal v0.92.0 h1:1GCj5swGzCZQphHqzt1OSsA/vOmAgFLoydY8bBqAhs4= -go.opentelemetry.io/collector/config/internal v0.92.0/go.mod h1:rPjglfSd4K/kNLfH7TJO8AsstHGMmWTdntOqH7WiFLg= -go.opentelemetry.io/collector/confmap v0.92.0 h1:xz20zNIvF9ZA1eWE+MZmZunmdXPIP/fr33ZvU0QUSxg= -go.opentelemetry.io/collector/confmap v0.92.0/go.mod h1:CmqTszB2uwiJ9ieEqISdecuoVuyt3jMnJ/9kD53GYHs= -go.opentelemetry.io/collector/connector v0.92.0 h1:RgQAU1QKATCVGVPsVfUYF/6CsAblV02hNWcIh/YEq7w= -go.opentelemetry.io/collector/connector v0.92.0/go.mod h1:aWfeV4mEpnmiJbpFOZP7nudATb9ypW74qTsltEdS9PQ= -go.opentelemetry.io/collector/consumer v0.92.0 h1:twa8T0iR9KVglvRbwZ5OPKLXPCC2DO6gVhrgDZ47MPE= -go.opentelemetry.io/collector/consumer v0.92.0/go.mod h1:fBZqP7bou3I7pDhWjleBuzdaLfQgJBc92wPJVOcKaGU= -go.opentelemetry.io/collector/exporter v0.92.0 h1:z6u+/hswJUuZbuPYIF2gXMZsqjIDd/tJO60XjLM850U= -go.opentelemetry.io/collector/exporter v0.92.0/go.mod h1:54ODYn1weY/Wr0bdxESj4P1fgyX+zaUsnJJnafORqIY= -go.opentelemetry.io/collector/exporter/debugexporter v0.92.0 h1:f+RjK3bJiBK/fg0Iizoobvlc4qHhQ98zy0yrFVYuSww= -go.opentelemetry.io/collector/exporter/debugexporter v0.92.0/go.mod h1:KvdXPSTiXawf/ZD1OlzU/t4c90kl6DkHCwvKf18sGGM= -go.opentelemetry.io/collector/exporter/otlpexporter v0.92.0 h1:t1Bw82ziGkilLdGFU7r7EeXrK+sH5V/iwafEeFD/kik= -go.opentelemetry.io/collector/exporter/otlpexporter v0.92.0/go.mod h1:zmZiMKuPrhPqcILsZbXg28V8biywyjzse5m3jjN6AB0= -go.opentelemetry.io/collector/extension v0.92.0 h1:zaehgW+LXCMNEb1d6Af/VHWphh5ZwX9aZl+NuQLGhpQ= -go.opentelemetry.io/collector/extension v0.92.0/go.mod h1:5EYwiaGU6deSY8YWqT5gvlnD850yJXP3NqFRKVVbYLs= -go.opentelemetry.io/collector/extension/auth v0.92.0 h1:FlCObeiYXsVStltFivg+gD5PSFUM6dXHigkgkUMitv0= -go.opentelemetry.io/collector/extension/auth v0.92.0/go.mod h1:fqCblNQV8Iz5w7Nrp1B865EJzKlVWS0aRgrr/c2HDDg= -go.opentelemetry.io/collector/extension/zpagesextension v0.92.0 h1:n2W8Lla4P22P88WJ+e1n/AtcAEO47WnSYXlUUideU8g= -go.opentelemetry.io/collector/extension/zpagesextension v0.92.0/go.mod h1:oZwtuGVYK8C3Uh4exR0v0KQSkIUkngA3h9qutnmn7Qo= +go.opentelemetry.io/collector v0.93.0 h1:wnyNd3OjwD7wmTIEVvyZG9cS+dhmfLAhNutWDgE5Vqo= +go.opentelemetry.io/collector v0.93.0/go.mod h1:lorK6TQaQvg0RDRN42HwY0Gqc/d7mvBgCMeJCYGishA= +go.opentelemetry.io/collector/component v0.93.0 h1:FHd86+7hbbBlDxdOFLWRA19HrjxKcXO+6H3UQ0zQz0c= +go.opentelemetry.io/collector/component v0.93.0/go.mod h1:8tglddCwOhrcktA7+EwYqcOL3+7xvbfn8ZwKcxsWch0= +go.opentelemetry.io/collector/config/configauth v0.93.0 h1:el5NR0VZ4naIf7hwcHw5LsxpYoComoMzUDB1HEgZ894= +go.opentelemetry.io/collector/config/configauth v0.93.0/go.mod h1:X0t0TR/DZMzzou1DkG/UdNzFubmOf4WSOidPLeqX54U= +go.opentelemetry.io/collector/config/configcompression v0.93.0 h1:mF9faTs/nU0Uceb+T1kqnUnfrOMqC1hABoFb7nai7Ig= +go.opentelemetry.io/collector/config/configcompression v0.93.0/go.mod h1:fA36AZC/Qcyl+HvMnvFZuV/iUWGQJrchimmk+qYWuMM= +go.opentelemetry.io/collector/config/configgrpc v0.93.0 h1:OSDTuJNL8/EaI4CS1SJF+ea7+b11U+j+HP8dlFVPIBU= +go.opentelemetry.io/collector/config/configgrpc v0.93.0/go.mod h1:gGXBMlaDRyOA9fWK/nb6a/D4yMEIZkLjl5/qtyU3ix8= +go.opentelemetry.io/collector/config/confighttp v0.93.0 h1:H8tiKryH5koh5aHfIdM2kgxQkuHrLtgKi6BL9PysvnA= +go.opentelemetry.io/collector/config/confighttp v0.93.0/go.mod h1:5doQNLIZoUhJJJzpAaMSzGgztAPcvdzTYnynIfJvtkY= +go.opentelemetry.io/collector/config/confignet v0.93.0 h1:UZ3ZGxbf0HBCNAIfxhfmVRal5gjDjocVed4NOs89hNo= +go.opentelemetry.io/collector/config/confignet v0.93.0/go.mod h1:rraribsOoZsYZm51+3TXHavmXKJOC5a5/X20vfmNbdw= +go.opentelemetry.io/collector/config/configopaque v0.93.0 h1:mvJFVhToyL6k0BZMhZTbSAxwYXGHoqibp6JVYY5SZu8= +go.opentelemetry.io/collector/config/configopaque v0.93.0/go.mod h1:dQK8eUXjIGKaw1RB7UIg2nqx56AueNxeKFCdB0P1ypg= +go.opentelemetry.io/collector/config/configretry v0.93.0 h1:32JKlZWkGgCLpc1X7rfug6l2zmt8Nz9D2FrwJOVGNx4= +go.opentelemetry.io/collector/config/configretry v0.93.0/go.mod h1:gt1HRYyMxcMca9lbDLPbivQzsUCjVjkPAn/3S6fiD14= +go.opentelemetry.io/collector/config/configtelemetry v0.93.0 h1:s+J/zYXc0zRi346Dz4r5ynTPyI5wRtp+JrSyrSBSiSY= +go.opentelemetry.io/collector/config/configtelemetry v0.93.0/go.mod h1:2XLhyR/GVpWeZ2K044vCmrvH/d4Ewt0aD/y46avZyMU= +go.opentelemetry.io/collector/config/configtls v0.93.0 h1:m6M4m5EM1e1BmhGwB4kEwm6TBslvjCYDdZViRBvtgW0= +go.opentelemetry.io/collector/config/configtls v0.93.0/go.mod h1:ehXx933OgUTSH7bIWphIf1Kfohy6qmrVHizFCgHtF7U= +go.opentelemetry.io/collector/config/internal v0.93.0 h1:tFGp6z3ieOQMs02Lpkezvr9ZJLRooVdOf3jyJGoTeiM= +go.opentelemetry.io/collector/config/internal v0.93.0/go.mod h1:rPjglfSd4K/kNLfH7TJO8AsstHGMmWTdntOqH7WiFLg= +go.opentelemetry.io/collector/confmap v0.93.0 h1:uYiak0iPuSW4BQIEuN+yihQqvWRwURhoW/qoVs4vLFA= +go.opentelemetry.io/collector/confmap v0.93.0/go.mod h1:+QxYr8qSah4ffcVBUC2KJgwlMsrD2nK1CmcHkLB+D7A= +go.opentelemetry.io/collector/connector v0.93.0 h1:h75WUN8opiO+ymOzmsaKo5k/6iDkqcBFvTO3kxiTozM= +go.opentelemetry.io/collector/connector v0.93.0/go.mod h1:RK1yq+Jpl71BugaPVt6oJwXQ150E4bwYHReQwhTqoK0= +go.opentelemetry.io/collector/consumer v0.93.0 h1:tt9T8knyamBr/85VqIbESsIHVkFXCkwOD+noFqK3+Vg= +go.opentelemetry.io/collector/consumer v0.93.0/go.mod h1:6BI1qsWw89DmTjoEu/acTcvTLISt3Y0lHioUfafpsAE= +go.opentelemetry.io/collector/exporter v0.93.0 h1:54EhAgvPM/eokfu0dK/k0qNb/vivPD2FdrLhYzvWWms= +go.opentelemetry.io/collector/exporter v0.93.0/go.mod h1:iT3oq6Hz6VwCZld0+SssBmQeSDqWCIjvf5dksRzhJ1s= +go.opentelemetry.io/collector/exporter/debugexporter v0.93.0 h1:uT1AQBC54KlHrlrrDIvdEZPooCQDDsP23tqUAJxaXlQ= +go.opentelemetry.io/collector/exporter/debugexporter v0.93.0/go.mod h1:LdaeHR1xfYGEKstw2TnurOrrhN96Qg6GELXSiO5Dkdo= +go.opentelemetry.io/collector/exporter/otlpexporter v0.93.0 h1:3UKgNJcXJ0csEIhJ5/UQVwsRiid/eg8l68aOIjI8vO0= +go.opentelemetry.io/collector/exporter/otlpexporter v0.93.0/go.mod h1:xhobg7vtcZhzNOFAr2Cm1ZPDS5MUcrTUJ+z+9pX6GzE= +go.opentelemetry.io/collector/extension v0.93.0 h1:HqSiVElfK78/rzSN4e7iyQXuMjsye0YZwZfJfalKKaQ= +go.opentelemetry.io/collector/extension v0.93.0/go.mod h1:KCZuD2WjQSoquIfjjOb18L8TfLrvbGgZW1H445umoMU= +go.opentelemetry.io/collector/extension/auth v0.93.0 h1:NgBT/P3kPJtnrdufIGGX7wbv8WcW3suYC6CcnCbw/Rk= +go.opentelemetry.io/collector/extension/auth v0.93.0/go.mod h1:cc15RY21t3D+cJMubhs2dMIedHS782L/7wfhCdL+pgk= +go.opentelemetry.io/collector/extension/zpagesextension v0.93.0 h1:cOTVR+8HlV5P8/ZNHxNtxcAUqw88InNjGuM8YL4KmnI= +go.opentelemetry.io/collector/extension/zpagesextension v0.93.0/go.mod h1:bSw32vI/g29g9Xx7GOHuGO7ap6NodoUO8qHankPKM9M= go.opentelemetry.io/collector/featuregate v1.0.1 h1:ok//hLSXttBbyu4sSV1pTx1nKdr5udSmrWy5sFMIIbM= go.opentelemetry.io/collector/featuregate v1.0.1/go.mod h1:QQXjP4etmJQhkQ20j4P/rapWuItYxoFozg/iIwuKnYg= -go.opentelemetry.io/collector/otelcol v0.92.0 h1:F2plXKY8/ULnVOvQPHrSOEUE8OSGEcBhJIntzT+BRKI= -go.opentelemetry.io/collector/otelcol v0.92.0/go.mod h1:8UUTPe216UnLQ8LQJtTp+WZpyrUF/nLWoVpT73MGV/k= +go.opentelemetry.io/collector/otelcol v0.93.0 h1:a6RT0DNK85zIH4E9sFQ4BVGu6ppR09lEJokEEDLpF+s= +go.opentelemetry.io/collector/otelcol v0.93.0/go.mod h1:6PbnYxuob3AMrqeKhkPYw1wOHdLW0QZIvhCVshDuIac= go.opentelemetry.io/collector/pdata v1.0.1 h1:dGX2h7maA6zHbl5D3AsMnF1c3Nn+3EUftbVCLzeyNvA= go.opentelemetry.io/collector/pdata v1.0.1/go.mod h1:jutXeu0QOXYY8wcZ/hege+YAnSBP3+jpTqYU1+JTI5Y= -go.opentelemetry.io/collector/processor v0.92.0 h1:fbtBPdtQbFZWOhPfgx6LXZM0fwQRHvjE3NeJS1d1GPg= -go.opentelemetry.io/collector/processor v0.92.0/go.mod h1:7UFWYbuXy/GC5eyUYsGPn2FpQzOY22sgW4QykXspAFE= -go.opentelemetry.io/collector/processor/batchprocessor v0.92.0 h1:dLcXaOQVpEhevZdPlfa3zWGbceMZxatTFcRi+XpRBnE= -go.opentelemetry.io/collector/processor/batchprocessor v0.92.0/go.mod h1:ecE0bXWi0OckZg98ElvBtXjPxpMw8quSE0FurbL2tsA= -go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.92.0 h1:BC2fE/gxjlw9oqxQmAU7taLAiiigFeJM6slSXQfXrlI= -go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.92.0/go.mod h1:m1XAO859A1wrKco8K5wmJhnaXzeQEPzu3jj4F3mqvUI= -go.opentelemetry.io/collector/receiver v0.92.0 h1:TRz4ufr5bFEszpAWgYVEx/b7VPZzEcECsyMzztf5PsQ= -go.opentelemetry.io/collector/receiver v0.92.0/go.mod h1:bYAAYbMuUVj3wx7ave2iyyJ+aGUpACliYOQ5xI92I7k= -go.opentelemetry.io/collector/receiver/otlpreceiver v0.92.0 h1:77oFMYYJfRu4yqlRkExMHDieg9gPv38UsMtK/0cu5kU= -go.opentelemetry.io/collector/receiver/otlpreceiver v0.92.0/go.mod h1:eZIrA6CY6xcm9uu3hmycS+L9kmBzyXE66Ci8FwkJpmI= -go.opentelemetry.io/collector/semconv v0.92.0 h1:3+OGPPuVu4rtrz8qGbpbiw7eKKULj4iJaSDTV52HM40= -go.opentelemetry.io/collector/semconv v0.92.0/go.mod h1:gZ0uzkXsN+J5NpiRcdp9xOhNGQDDui8Y62p15sKrlzo= -go.opentelemetry.io/collector/service v0.92.0 h1:KhicjajrbhEpjzSYCHvVZBYW5Qvd/UXi88oCegSanZI= -go.opentelemetry.io/collector/service v0.92.0/go.mod h1:hlq/Vyj0un+HKx8nAI77eaK/mABNL8hhPH7rKh9SOu4= +go.opentelemetry.io/collector/processor v0.93.0 h1:P4/AXaeMNzmImsD1dONlLOk5Ky4txS+Yf52eIulIg0k= +go.opentelemetry.io/collector/processor v0.93.0/go.mod h1:VQqYLgdC04Bp8ArfkERaOFaRCDvyCMdwULvTn66l6AA= +go.opentelemetry.io/collector/processor/batchprocessor v0.93.0 h1:Rtgz8QP2QcaNDZLiZePPKYZRMEAWgUeHQ5jK01BoZb8= +go.opentelemetry.io/collector/processor/batchprocessor v0.93.0/go.mod h1:EOPyy13iMmEiTwYRur3j5SA/H1LSfdOMjHkT+I+aVKw= +go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.93.0 h1:hPHnvscj6BQTzexTmzKUYmTSgMAyb7oTNDva2TWUPw0= +go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.93.0/go.mod h1:vWdmZb7J5clvmIeL63QUvXf7uQIrQyVVUf5i18ct4Ew= +go.opentelemetry.io/collector/receiver v0.93.0 h1:oIMAqtG3b3tk+bokCK9T2kAmnFPtYKkph2hmtKcaDR8= +go.opentelemetry.io/collector/receiver v0.93.0/go.mod h1:g2cx676T4pd7WfTabvPkML2K5ksLEmP3DfWBUrHrV8A= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.93.0 h1:tSvdm8BmQYvLSe9b0Lrn4oUup3Zs1qwthjkwRcNW4sA= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.93.0/go.mod h1:KOvsNtNy4fpOrqjveurQ7049NH+xkBhOYLeSOXwRNJ8= +go.opentelemetry.io/collector/semconv v0.93.0 h1:eBlMcVNTwYYsVdAsCVDs4wvVYs75K1xcIDpqj16PG4c= +go.opentelemetry.io/collector/semconv v0.93.0/go.mod h1:gZ0uzkXsN+J5NpiRcdp9xOhNGQDDui8Y62p15sKrlzo= +go.opentelemetry.io/collector/service v0.93.0 h1:U2pUgqwo7X+gi9LqPOQe/QQoYdv0DtJ4S00r+oPf8bY= +go.opentelemetry.io/collector/service v0.93.0/go.mod h1:qMQ8tWwwBnhUe0Vp6jkml/r66+Pg1t1j2U5DOpLeRlE= go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/config v0.1.1 h1:lIUTrMWkfDE0GvzBLhwv6ATDB1vntrnTsRvUMkZKnfQ= -go.opentelemetry.io/contrib/config v0.1.1/go.mod h1:rDrK4+PS6Cs+WIphU/GO5Sk4TGV36lEQqk/Z1vZkaLI= +go.opentelemetry.io/contrib/config v0.2.0 h1:VRYXnoE2ug3QOtaKka4eV9OgHXMJ0q6ggFtx6s+Jvy0= +go.opentelemetry.io/contrib/config v0.2.0/go.mod h1:iBfwdwpZBKsVXMOAWHyGS8//dcVNJORYnFm6VNqsOG8= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= -go.opentelemetry.io/contrib/propagators/b3 v1.21.1 h1:WPYiUgmw3+b7b3sQ1bFBFAf0q+Di9dvNc3AtYfnT4RQ= -go.opentelemetry.io/contrib/propagators/b3 v1.21.1/go.mod h1:EmzokPoSqsYMBVK4nRnhsfm5mbn8J1eDuz/U1UaQaWg= -go.opentelemetry.io/contrib/zpages v0.46.1 h1:U8Hh84dc+vJTVgRnL+QKWtWD2iqTSKibrQ85EeQqsNg= -go.opentelemetry.io/contrib/zpages v0.46.1/go.mod h1:1Wq9YTzkhr3Jkyi/sVrasFSppVzJQcvFf2Vc2ExZd6c= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/propagators/b3 v1.22.0 h1:Okbgv0pWHMQq+mF7H2o1mucJ5PvxKFq2c8cyqoXfeaQ= +go.opentelemetry.io/contrib/propagators/b3 v1.22.0/go.mod h1:N3z0ycFRhsVZ+tG/uavMxHvOvFE95QM6gwW1zSqT9dQ= +go.opentelemetry.io/contrib/zpages v0.47.0 h1:ekpdNa2wqOvAfwZIGDIIV02zmR+z08aWPt21KrPJnaU= +go.opentelemetry.io/contrib/zpages v0.47.0/go.mod h1:rBeFA/UxnMjRlEGpmClIqzf1mCIKtl7ahjww3wsSdGs= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/bridge/opencensus v0.44.0 h1:/inELPJztkn6Xx3ap9qw8i8XdeWF0B/OjGHOdRTePZ8= -go.opentelemetry.io/otel/bridge/opencensus v0.44.0/go.mod h1:dQTBJVBx1xahrXEFBV1BGPAnGuXC92LCj55fxIrtj7I= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/bridge/opencensus v0.45.0 h1:kEOlv9Exuv3J8GCf1nLMHfrTPGnZOuIkN8YlRM14TtQ= +go.opentelemetry.io/otel/bridge/opencensus v0.45.0/go.mod h1:tkVMJeFOr43+zzwbxtIWsNcCCDT7rI5/c9rhMfMIENg= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 h1:bflGWrfYyuulcdxf14V6n9+CoQcu5SAAdHmDPAJnlps= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0/go.mod h1:qcTO4xHAxZLaLxPd60TdE88rxtItPHgHWqOhOGRr0as= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.45.0 h1:tfil6di0PoNV7FZdsCS7A5izZoVVQ7AuXtyekbOpG/I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.45.0/go.mod h1:AKFZIEPOnqB00P63bTjOiah4ZTaRzl1TKwUWpZdYUHI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.45.0 h1:+RbSCde0ERway5FwKvXR3aRJIFeDu9rtwC6E7BC6uoM= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.45.0/go.mod h1:zcI8u2EJxbLPyoZ3SkVAAcQPgYb1TDRzW93xLFnsggU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 h1:H2JFgRcGiyHg7H7bwcwaQJYrNFqCqrbTQ8K4p1OvDu8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0/go.mod h1:WfCWp1bGoYK8MeULtI15MmQVczfR+bFkk0DF3h06QmQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/prometheus v0.44.1-0.20231201153405-6027c1ae76f2 h1:TnhkxGJ5qPHAMIMI4r+HPT/BbpoHxqn4xONJrok054o= -go.opentelemetry.io/otel/exporters/prometheus v0.44.1-0.20231201153405-6027c1ae76f2/go.mod h1:ERL2uIeBtg4TxZdojHUwzZfIFlUIjZtxubT5p4h1Gjg= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.44.0 h1:dEZWPjVN22urgYCza3PXRUGEyCB++y1sAqm6guWFesk= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.44.0/go.mod h1:sTt30Evb7hJB/gEk27qLb1+l9n4Tb8HvHkR0Wx3S6CU= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 h1:FyjCyI9jVEfqhUh2MoSkmolPjfh5fp2hnV0b0irxH4Q= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0/go.mod h1:hYwym2nDEeZfG/motx0p7L7J1N1vyzIThemQsb4g2qY= +go.opentelemetry.io/otel/exporters/prometheus v0.45.0 h1:BeIK2KGho0oCWa7LxEGSqfDZbs7Fpv/Viz+FS4P8CXE= +go.opentelemetry.io/otel/exporters/prometheus v0.45.0/go.mod h1:UVJZPLnfDSvHj+eJuZE+E1GjIBD267mEMfAAHJdghWg= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.45.0 h1:NjN6zc7Mwy9torqa3mo+pMJ3mHoPI0uzVSYcqB2t72A= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.45.0/go.mod h1:U+T5v2bk4fCC8XdSEWZja3Pm/ZhvV/zE7JwX/ELJKts= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.22.0 h1:zr8ymM5OWWjjiWRzwTfZ67c905+2TMHYp2lMJ52QTyM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.22.0/go.mod h1:sQs7FT2iLVJ+67vYngGJkPe1qr39IzaBzaj9IDNNY8k= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= -go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= +go.opentelemetry.io/otel/sdk/metric v1.22.0 h1:ARrRetm1HCVxq0cbnaZQlfwODYJHo3gFL8Z3tSmHBcI= +go.opentelemetry.io/otel/sdk/metric v1.22.0/go.mod h1:KjQGeMIDlBNEOo6HvjhxIec1p/69/kULDcp4gr0oLQQ= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= @@ -2311,8 +2306,8 @@ golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2470,7 +2465,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/pkg/agent/application/actions/handlers/handler_action_policy_change.go b/internal/pkg/agent/application/actions/handlers/handler_action_policy_change.go index 25d7b2bdd4e..c4f2c10dc96 100644 --- a/internal/pkg/agent/application/actions/handlers/handler_action_policy_change.go +++ b/internal/pkg/agent/application/actions/handlers/handler_action_policy_change.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net/http" "sort" "time" @@ -198,7 +197,7 @@ func (h *PolicyChangeHandler) handleFleetServerHosts(ctx context.Context, c *con } // discard body for proper cancellation and connection reuse - _, _ = io.Copy(ioutil.Discard, resp.Body) + _, _ = io.Copy(io.Discard, resp.Body) resp.Body.Close() reader, err := fleetToReader(h.agentInfo, h.config) diff --git a/internal/pkg/agent/application/application.go b/internal/pkg/agent/application/application.go index c277382ae93..c5619e5293b 100644 --- a/internal/pkg/agent/application/application.go +++ b/internal/pkg/agent/application/application.go @@ -28,6 +28,7 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/capabilities" "github.com/elastic/elastic-agent/internal/pkg/composable" "github.com/elastic/elastic-agent/internal/pkg/config" + "github.com/elastic/elastic-agent/internal/pkg/otel" "github.com/elastic/elastic-agent/internal/pkg/release" "github.com/elastic/elastic-agent/pkg/component" "github.com/elastic/elastic-agent/pkg/component/runtime" @@ -46,10 +47,11 @@ func New( testingMode bool, fleetInitTimeout time.Duration, disableMonitoring bool, + runAsOtel bool, modifiers ...component.PlatformModifier, ) (*coordinator.Coordinator, coordinator.ConfigManager, composable.Controller, error) { - err := version.InitVersionInformation() + err := version.InitVersionError() if err != nil { // non-fatal error, log a warning and move on log.With("error.message", err).Warnf("Error initializing version information: falling back to %s", release.Version()) @@ -144,6 +146,9 @@ func New( log.Debugf("Reloading of configuration is on, frequency is set to %s", cfg.Settings.Reload.Period) configMgr = newPeriodic(log, cfg.Settings.Reload.Period, discover, loader) } + } else if runAsOtel { + // ignoring configuration in elastic-agent.yml + configMgr = otel.NewOtelModeConfigManager() } else { isManaged = true var store storage.Store diff --git a/internal/pkg/agent/application/application_test.go b/internal/pkg/agent/application/application_test.go index cf67f19c6cf..37744a54a3e 100644 --- a/internal/pkg/agent/application/application_test.go +++ b/internal/pkg/agent/application/application_test.go @@ -63,6 +63,7 @@ func TestLimitsLog(t *testing.T) { true, // testingMode time.Millisecond, // fleetInitTimeout true, // disable monitoring + false, // not otel mode ) require.NoError(t, err) diff --git a/internal/pkg/agent/application/coordinator/coordinator.go b/internal/pkg/agent/application/coordinator/coordinator.go index bfd14a91381..0a5450ddada 100644 --- a/internal/pkg/agent/application/coordinator/coordinator.go +++ b/internal/pkg/agent/application/coordinator/coordinator.go @@ -8,6 +8,7 @@ import ( "context" "errors" "fmt" + "reflect" "strings" "time" @@ -298,6 +299,28 @@ type managerChans struct { upgradeMarkerUpdate <-chan upgrade.UpdateMarker } +// diffCheck is a container used by checkAndLogUpdate() +type diffCheck struct { + inNew bool + inLast bool + updated bool +} + +// UpdateStats reports the diff of a component update. +// This is primarily used as a log message, and exported in case it's needed elsewhere. +type UpdateStats struct { + Components UpdateComponentChange `json:"components"` + Outputs UpdateComponentChange `json:"outputs"` +} + +// UpdateComponentChange reports stats for changes to a particular part of a config. +type UpdateComponentChange struct { + Added []string `json:"added,omitempty"` + Removed []string `json:"removed,omitempty"` + Updated []string `json:"updated,omitempty"` + Count int `json:"count,omitempty"` +} + // New creates a new coordinator. func New(logger *logger.Logger, cfg *configuration.Configuration, logLevel logp.Level, agentInfo *info.AgentInfo, specs component.RuntimeSpecs, reexecMgr ReExecManager, upgradeMgr UpgradeManager, runtimeMgr RuntimeManager, configMgr ConfigManager, varsMgr VarsManager, caps capabilities.Capabilities, monitorMgr MonitorManager, isManaged bool, modifiers ...ComponentsModifier) *Coordinator { var fleetState cproto.State @@ -1216,10 +1239,149 @@ func (c *Coordinator) generateComponentModel() (err error) { // If we made it this far, update our internal derived values and // return with no error c.derivedConfig = cfg + + lastComponentModel := c.componentModel c.componentModel = comps + + c.checkAndLogUpdate(lastComponentModel) + return nil } +// compares the last component model with an updated model, +// logging any differences. +func (c *Coordinator) checkAndLogUpdate(lastComponentModel []component.Component) { + if lastComponentModel == nil { + c.logger.Debugf("Received initial component update; total of %d components", len(c.componentModel)) + return + } + + type compCheck struct { + inCurrent bool + inLast bool + + diffUnits map[string]diffCheck + } + + lastCompMap := convertComponentListToMap(lastComponentModel) + currentCompMap := convertComponentListToMap(c.componentModel) + + compDiffMap := map[string]compCheck{} + outDiffMap := map[string]diffCheck{} + // kinda-callbacks for dealing with output logic + foundInLast := func(outName string) { + if outDiff, ok := outDiffMap[outName]; ok { + outDiff.inLast = true + outDiffMap[outName] = outDiff + } else { + outDiffMap[outName] = diffCheck{inLast: true} + } + } + + foundInUpdated := func(outName string) { + if outDiff, ok := outDiffMap[outName]; ok { + outDiff.inNew = true + outDiffMap[outName] = outDiff + } else { + outDiffMap[outName] = diffCheck{inNew: true} + } + } + + // diff the maps + + // find added & updated components + for id, comp := range currentCompMap { + // check output + foundInUpdated(comp.OutputType) + // compare with last state + diff := compCheck{inCurrent: true} + if lastComp, ok := lastCompMap[id]; ok { + diff.inLast = true + // if the unit is in both the past and previous, check for updated units + diff.diffUnits = diffUnitList(lastComp.Units, comp.Units) + foundInLast(lastComp.OutputType) + // a bit of optimization: after we're done, we'll need to iterate over lastCompMap to fetch removed units, + // so delete items we don't need to iterate over + delete(lastCompMap, id) + } + compDiffMap[id] = diff + } + + // find removed components + // if something is still in this map, that means it's only in this map + for id, comp := range lastCompMap { + compDiffMap[id] = compCheck{inLast: true} + foundInLast(comp.OutputType) + } + + addedList := []string{} + removedList := []string{} + + formattedUpdated := []string{} + + // reduced to list of added/removed outputs + addedOutputs := []string{} + removedOutputs := []string{} + + // take our diff map and format everything for output + for id, diff := range compDiffMap { + if diff.inLast && !diff.inCurrent { + removedList = append(removedList, id) + } + if !diff.inLast && diff.inCurrent { + addedList = append(addedList, id) + } + // format a user-readable list of diffs + if diff.inLast && diff.inCurrent { + units := []string{} + for unitId, state := range diff.diffUnits { + action := "" + if state.inLast && !state.inNew { + action = "removed" + } + if state.inNew && !state.inLast { + action = "added" + } + if state.updated { + action = "updated" + } + if action != "" { + units = append(units, fmt.Sprintf("(%s: %s)", unitId, action)) + } + } + if len(units) > 0 { + formatted := fmt.Sprintf("%s: %v", id, units) + formattedUpdated = append(formattedUpdated, formatted) + } + } + } + + // format outputs + for output, comp := range outDiffMap { + if comp.inLast && !comp.inNew { + removedOutputs = append(removedOutputs, output) + } + if !comp.inLast && comp.inNew { + addedOutputs = append(addedOutputs, output) + } + } + + logStruct := UpdateStats{ + Components: UpdateComponentChange{ + Added: addedList, + Removed: removedList, + Count: len(c.componentModel), + Updated: formattedUpdated, + }, + Outputs: UpdateComponentChange{ + Added: addedOutputs, + Removed: removedOutputs, + }, + } + + c.logger.Infow("component model updated", "changes", logStruct) +} + // Filter any inputs and outputs in the generated component model // based on whether they're excluded by the capabilities config func (c *Coordinator) filterByCapabilities(comps []component.Component) []component.Component { @@ -1243,6 +1405,48 @@ func (c *Coordinator) filterByCapabilities(comps []component.Component) []compon return result } +// helpers for checkAndLogUpdate + +func convertUnitListToMap(unitList []component.Unit) map[string]component.Unit { + unitMap := map[string]component.Unit{} + for _, c := range unitList { + unitMap[c.ID] = c + } + return unitMap +} + +func convertComponentListToMap(compList []component.Component) map[string]component.Component { + compMap := map[string]component.Component{} + for _, c := range compList { + compMap[c.ID] = c + } + return compMap +} + +func diffUnitList(old, new []component.Unit) map[string]diffCheck { + oldMap := convertUnitListToMap(old) + newMap := convertUnitListToMap(new) + + diffMap := map[string]diffCheck{} + // find new and updated units + for id, newUnits := range newMap { + diff := diffCheck{inNew: true} + if oldUnit, ok := oldMap[id]; ok { + diff.inLast = true + if newUnits.Config != nil && oldUnit.Config != nil && newUnits.Config.GetSource() != nil && oldUnit.Config.GetSource() != nil { + diff.updated = !reflect.DeepEqual(newUnits.Config.GetSource().AsMap(), oldUnit.Config.GetSource().AsMap()) + } + delete(oldMap, id) + } + diffMap[id] = diff + } + // find removed units + for id := range oldMap { + diffMap[id] = diffCheck{inLast: true} + } + return diffMap +} + // collectManagerErrors listens on the shutdown channels for the // runtime, config, and vars managers as well as the upgrade marker // watcher and waits for up to the specified timeout for them to diff --git a/internal/pkg/agent/application/coordinator/coordinator_test.go b/internal/pkg/agent/application/coordinator/coordinator_test.go index 49770bc1e97..3cfeddb32af 100644 --- a/internal/pkg/agent/application/coordinator/coordinator_test.go +++ b/internal/pkg/agent/application/coordinator/coordinator_test.go @@ -15,7 +15,7 @@ import ( "testing" "time" - "github.com/elastic/elastic-agent-client/v7/pkg/client" + "google.golang.org/protobuf/types/known/structpb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -24,6 +24,8 @@ import ( "github.com/elastic/elastic-agent-libs/logp" + "github.com/elastic/elastic-agent-client/v7/pkg/client" + "github.com/elastic/elastic-agent-client/v7/pkg/proto" "github.com/elastic/elastic-agent/internal/pkg/agent/application/info" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" "github.com/elastic/elastic-agent/internal/pkg/agent/application/reexec" @@ -97,6 +99,231 @@ func waitForState( } } +func TestComponentUpdateDiff(t *testing.T) { + + err := logp.DevelopmentSetup(logp.ToObserverOutput()) + require.NoError(t, err) + + cases := []struct { + name string + old []component.Component + new []component.Component + logtest func(t *testing.T, logs UpdateStats) + }{ + { + name: "test-basic-removed", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + }, + { + ID: "component-two", + OutputType: "kafka", + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + + require.Equal(t, []string{"component-two"}, logs.Components.Removed) + require.Equal(t, []string{"kafka"}, logs.Outputs.Removed) + }, + }, + { + name: "test-added-and-removed", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + }, + { + ID: "component-two", + OutputType: "kafka", + }, + }, + new: []component.Component{ + { + ID: "component-three", + OutputType: "elasticsearch", + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.Equal(t, 2, len(logs.Components.Removed)) + require.Equal(t, []string{"component-three"}, logs.Components.Added) + require.Equal(t, []string{"kafka"}, logs.Outputs.Removed) + }, + }, + { + name: "test-updated-component", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + {ID: "unit-one"}, + {ID: "unit-two"}, + {ID: "unit-x"}, + }, + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + {ID: "unit-one"}, + {ID: "unit-two"}, + {ID: "unit-three"}, + }, + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.Contains(t, logs.Components.Updated[0], "unit-three: added") + require.Contains(t, logs.Components.Updated[0], "unit-x: removed") + }, + }, + { + name: "just-change-output", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "logstash", + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.Equal(t, []string{"elasticsearch"}, logs.Outputs.Removed) + require.Equal(t, []string{"logstash"}, logs.Outputs.Added) + }, + }, + { + name: "config-update", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Source: mustNewStruct(t, map[string]interface{}{"example": "value"})}, + }, + }, + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Source: mustNewStruct(t, map[string]interface{}{"example": "two"})}, + }, + }, + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.NotEmpty(t, logs.Components.Updated) + }, + }, + { + name: "config-no-changes", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Source: mustNewStruct(t, map[string]interface{}{"example": "value"})}, + }, + }, + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Source: mustNewStruct(t, map[string]interface{}{"example": "value"})}, + }, + }, + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.Len(t, logs.Components.Updated, 0) + }, + }, + { + name: "config-source-nil", + old: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Id: "test"}, + }, + }, + }, + }, + new: []component.Component{ + { + ID: "component-one", + OutputType: "elasticsearch", + Units: []component.Unit{ + { + ID: "unit-one", + Config: &proto.UnitExpectedConfig{Id: "test"}, + }, + }, + }, + }, + logtest: func(t *testing.T, logs UpdateStats) { + require.Len(t, logs.Components.Updated, 0) + }, + }, + } + + for _, testcase := range cases { + + t.Run(testcase.name, func(t *testing.T) { + testCoord := Coordinator{ + logger: logp.L(), + componentModel: testcase.new, + } + testCoord.checkAndLogUpdate(testcase.old) + + obsLogs := logp.ObserverLogs().TakeAll() + last := obsLogs[len(obsLogs)-1] + + // extract the structured data from the log message + testcase.logtest(t, last.Context[0].Interface.(UpdateStats)) + }) + + } + +} + +func mustNewStruct(t *testing.T, v map[string]interface{}) *structpb.Struct { + str, err := structpb.NewStruct(v) + require.NoError(t, err) + return str +} + func TestCoordinator_State_Starting(t *testing.T) { coordCh := make(chan error) ctx, cancel := context.WithCancel(context.Background()) diff --git a/internal/pkg/agent/application/filelock/locker_test.go b/internal/pkg/agent/application/filelock/locker_test.go index 1b7f764fb71..51191e6c0ea 100644 --- a/internal/pkg/agent/application/filelock/locker_test.go +++ b/internal/pkg/agent/application/filelock/locker_test.go @@ -5,7 +5,6 @@ package filelock import ( - "io/ioutil" "os" "testing" @@ -16,7 +15,7 @@ import ( const testLockFile = "test.lock" func TestAppLocker(t *testing.T) { - tmp, _ := ioutil.TempDir("", "locker") + tmp, _ := os.MkdirTemp("", "locker") defer os.RemoveAll(tmp) locker1 := NewAppLocker(tmp, testLockFile) diff --git a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go index de40565c0b5..4c28aa8c0b2 100644 --- a/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go +++ b/internal/pkg/agent/application/gateway/fleet/fleet_gateway_test.go @@ -11,7 +11,6 @@ import ( "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -115,7 +114,7 @@ func wrapStrToResp(code int, body string) *http.Response { Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, - Body: ioutil.NopCloser(bytes.NewBufferString(body)), + Body: io.NopCloser(bytes.NewBufferString(body)), ContentLength: int64(len(body)), Header: make(http.Header), } @@ -499,7 +498,7 @@ func runFleetGateway(ctx context.Context, g coordinator.FleetGateway) <-chan err } func newStateStore(t *testing.T, log *logger.Logger) *store.StateStore { - dir, err := ioutil.TempDir("", "fleet-gateway-unit-test") + dir, err := os.MkdirTemp("", "fleet-gateway-unit-test") require.NoError(t, err) filename := filepath.Join(dir, "state.enc") diff --git a/internal/pkg/agent/application/monitoring/process.go b/internal/pkg/agent/application/monitoring/process.go index f89597c6d03..dc969553d09 100644 --- a/internal/pkg/agent/application/monitoring/process.go +++ b/internal/pkg/agent/application/monitoring/process.go @@ -8,7 +8,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "strings" "syscall" @@ -174,7 +174,7 @@ func processMetrics(ctx context.Context, endpoint, path string) ([]byte, int, er } defer resp.Body.Close() - rb, err := ioutil.ReadAll(resp.Body) + rb, err := io.ReadAll(resp.Body) if err != nil { return nil, 0, errorWithStatus(http.StatusInternalServerError, err) } diff --git a/internal/pkg/agent/application/paths/common.go b/internal/pkg/agent/application/paths/common.go index 61ff0bcdc49..5a2a458744d 100644 --- a/internal/pkg/agent/application/paths/common.go +++ b/internal/pkg/agent/application/paths/common.go @@ -5,6 +5,7 @@ package paths import ( + "errors" "flag" "fmt" "os" @@ -15,6 +16,9 @@ import ( "github.com/elastic/elastic-agent/internal/pkg/release" "github.com/elastic/elastic-agent/pkg/utils" + + // this is not a leftover: this anonymous import is needed for version initialization + _ "github.com/elastic/elastic-agent/version" ) const ( @@ -59,6 +63,7 @@ var ( ) func init() { + // this is the first call where we need version information (it calls isInsideData()) topPath = initialTop() configPath = topPath logsPath = topPath @@ -191,7 +196,13 @@ func SetLogs(path string) { // VersionedHome returns a versioned path based on a TopPath and used commit. func VersionedHome(base string) string { - return filepath.Join(base, "data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit())) + versionedHomePath := filepath.Join(base, "data", fmt.Sprintf("elastic-agent-%s-%s", release.VersionWithSnapshot(), release.ShortCommit())) + _, err := os.Stat(versionedHomePath) + if errors.Is(err, os.ErrNotExist) { + // fallback to the legacy elastic-agent- path + versionedHomePath = filepath.Join(base, "data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit())) + } + return versionedHomePath } // Downloads returns the downloads directory for Agent @@ -253,8 +264,9 @@ func retrieveExecutableDir() string { // isInsideData returns true when the exePath is inside of the current Agents data path. func isInsideData(exeDir string) bool { - expectedDir := binaryDir(filepath.Join("data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit()))) - return strings.HasSuffix(exeDir, expectedDir) + expectedDirLegacy := binaryDir(filepath.Join("data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit()))) + expectedDirWithVersion := binaryDir(filepath.Join("data", fmt.Sprintf("elastic-agent-%s-%s", release.VersionWithSnapshot(), release.ShortCommit()))) + return strings.HasSuffix(exeDir, expectedDirLegacy) || strings.HasSuffix(exeDir, expectedDirWithVersion) } // ExecDir returns the "executable" directory which is: @@ -326,3 +338,17 @@ func ControlSocketFromPath(platform string, path string) string { // for it to be used, but needs to be unique per Agent (in the case that multiple are running) return utils.SocketURLWithFallback(socketPath, path) } + +func pathSplit(path string) []string { + dir, file := filepath.Split(path) + if dir == "" && file == "" { + return []string{} + } + if dir == "" && file != "" { + return []string{file} + } + if dir == path { + return []string{} + } + return append(pathSplit(filepath.Clean(dir)), file) +} diff --git a/internal/pkg/agent/application/paths/common_test.go b/internal/pkg/agent/application/paths/common_test.go index 27a9cf80ebd..84c976aaa79 100644 --- a/internal/pkg/agent/application/paths/common_test.go +++ b/internal/pkg/agent/application/paths/common_test.go @@ -13,10 +13,14 @@ import ( "github.com/google/go-cmp/cmp" "github.com/elastic/elastic-agent/internal/pkg/release" + "github.com/elastic/elastic-agent/version" ) -func validTestPath() string { +func validTestPath(useVersionInPath bool) string { validPath := filepath.Join("data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit())) + if useVersionInPath { + validPath = filepath.Join("data", fmt.Sprintf("elastic-agent-%s-%s", version.GetAgentPackageVersion(), release.ShortCommit())) + } if runtime.GOOS == darwin { validPath = filepath.Join(validPath, "elastic-agent.app", "Contents", "MacOS") } @@ -25,6 +29,7 @@ func validTestPath() string { func TestIsInsideData(t *testing.T) { tests := []struct { + setup func(*testing.T) name string exePath string res bool @@ -38,13 +43,21 @@ func TestIsInsideData(t *testing.T) { }, { name: "valid", - exePath: validTestPath(), + exePath: validTestPath(false), + res: true, + }, + { + name: "valid with version in path", + exePath: validTestPath(true), res: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + if tc.setup != nil { + tc.setup(t) + } res := isInsideData(tc.exePath) diff := cmp.Diff(tc.res, res) if diff != "" { @@ -71,12 +84,12 @@ func TestExecDir(t *testing.T) { }, { name: "valid", - execDir: validTestPath(), + execDir: validTestPath(false), resDir: ".", }, { name: "valid abs", - execDir: filepath.Join(base, validTestPath()), + execDir: filepath.Join(base, validTestPath(false)), resDir: base, }, } @@ -91,3 +104,55 @@ func TestExecDir(t *testing.T) { }) } } + +func TestPathSplitUnix(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Skipping Unix tests on Windows") + } + tests := map[string]struct { + path string + want []string + }{ + "empty string": {path: "", want: []string{}}, + "just file": {path: "test.txt", want: []string{"test.txt"}}, + "just dir": {path: "/", want: []string{}}, + "top dir": {path: "/test.txt", want: []string{"test.txt"}}, + "simple": {path: "/a/b", want: []string{"a", "b"}}, + "long": {path: "/a/b c/d-e/f_g", want: []string{"a", "b c", "d-e", "f_g"}}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := pathSplit(tc.path) + if !cmp.Equal(tc.want, got) { + t.Fatalf("not equal got: %v, want: %v", got, tc.want) + } + }) + } +} + +func TestPathSplitWindows(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("Skipping Windows tests on non Windows") + } + tests := map[string]struct { + path string + want []string + }{ + "empty string": {path: "", want: []string{}}, + "just file": {path: "test.txt", want: []string{"test.txt"}}, + "just dir": {path: "C:\\", want: []string{}}, + "top dir": {path: "C:\\test.txt", want: []string{"test.txt"}}, + "simple": {path: "C:\\a\\b", want: []string{"a", "b"}}, + "long": {path: "C:\\a\\b c\\d-e\\f_g", want: []string{"a", "b c", "d-e", "f_g"}}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := pathSplit(tc.path) + if !cmp.Equal(tc.want, got) { + t.Fatalf("not equal got: %v, want: %v", got, tc.want) + } + }) + } +} diff --git a/internal/pkg/agent/application/paths/paths_test.go b/internal/pkg/agent/application/paths/paths_test.go index 2fd7584eb13..ffd0cb8d337 100644 --- a/internal/pkg/agent/application/paths/paths_test.go +++ b/internal/pkg/agent/application/paths/paths_test.go @@ -31,3 +31,64 @@ func TestEqual(t *testing.T) { }) } } + +func TestHasPrefixUnix(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Skipping unix HasPrefix tests on Windows host") + } + tests := map[string]struct { + path string + prefix string + want bool + }{ + "simple true": {path: "/a/b", prefix: "/a", want: true}, + "just root": {path: "/", prefix: "/", want: true}, + "root one dir": {path: "/a", prefix: "/", want: true}, + "simple false": {path: "/a/b", prefix: "/c/d", want: false}, + "prefix too long": {path: "/a/b", prefix: "/a/b/c/d", want: false}, + "trailing slash": {path: "/a/b/", prefix: "/a", want: true}, + "no path": {path: "", prefix: "/a", want: false}, + "no prefix": {path: "/a/b", prefix: "", want: false}, + "middle differ": {path: "/a/b/c", prefix: "/a/d/c", want: false}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := HasPrefix(tc.path, tc.prefix) + if got != tc.want { + t.Fatalf("got %v, expected %v", got, tc.want) + } + }) + } +} + +func TestHasPrefixWindows(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("Skipping windows HasPrefix tests on non Windows host") + } + tests := map[string]struct { + path string + prefix string + want bool + }{ + "simple true": {path: "c:\\a\\b", prefix: "c:\\a", want: true}, + "just root": {path: "c:\\", prefix: "c:\\", want: true}, + "root one dir": {path: "c:\\a", prefix: "c:\\", want: true}, + "simple false": {path: "c:\\a\\b", prefix: "c:\\c\\d", want: false}, + "prefix too long": {path: "c:\\a\\b", prefix: "c:\\a\\b\\c\\d", want: false}, + "trailing slash": {path: "c:\\a\\b\\", prefix: "c:\\a", want: true}, + "no path": {path: "", prefix: "c:\\a", want: false}, + "no prefix": {path: "c:\\a\\b", prefix: "", want: false}, + "case insensitive": {path: "C:\\A\\B", prefix: "c:\\a", want: true}, + "middle differ": {path: "c:\\a\\b\\c", prefix: "c:\\a\\d\\c", want: false}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got := HasPrefix(tc.path, tc.prefix) + if got != tc.want { + t.Fatalf("got %v, expected %v", got, tc.want) + } + }) + } +} diff --git a/internal/pkg/agent/application/paths/paths_unix.go b/internal/pkg/agent/application/paths/paths_unix.go index da905a4bb84..99d8cbe1ad5 100644 --- a/internal/pkg/agent/application/paths/paths_unix.go +++ b/internal/pkg/agent/application/paths/paths_unix.go @@ -7,6 +7,7 @@ package paths import ( + "path/filepath" "runtime" ) @@ -16,3 +17,28 @@ func initialControlSocketPath(topPath string) string { // ResolveControlSocket does nothing on non-Windows hosts. func ResolveControlSocket() {} + +// HasPrefix tests if the path starts with the prefix. +func HasPrefix(path string, prefix string) bool { + if path == "" || prefix == "" { + return false + } + + if filepath.VolumeName(path) != filepath.VolumeName(prefix) { + return false + } + + prefixParts := pathSplit(filepath.Clean(prefix)) + pathParts := pathSplit(filepath.Clean(path)) + + if len(prefixParts) > len(pathParts) { + return false + } + + for i := 0; i < len(prefixParts); i++ { + if prefixParts[i] != pathParts[i] { + return false + } + } + return true +} diff --git a/internal/pkg/agent/application/paths/paths_windows.go b/internal/pkg/agent/application/paths/paths_windows.go index a6f7b14afe7..dc5bc6ed921 100644 --- a/internal/pkg/agent/application/paths/paths_windows.go +++ b/internal/pkg/agent/application/paths/paths_windows.go @@ -67,3 +67,28 @@ func ResolveControlSocket() { SetControlSocket(WindowsControlSocketInstalledPath) } } + +// HasPrefix tests if the path starts with the prefix. +func HasPrefix(path string, prefix string) bool { + if path == "" || prefix == "" { + return false + } + + if !strings.EqualFold(filepath.VolumeName(path), filepath.VolumeName(prefix)) { + return false + } + + prefixParts := pathSplit(filepath.Clean(prefix)) + pathParts := pathSplit(filepath.Clean(path)) + + if len(prefixParts) > len(pathParts) { + return false + } + + for i := 0; i < len(prefixParts); i++ { + if !strings.EqualFold(prefixParts[i], pathParts[i]) { + return false + } + } + return true +} diff --git a/internal/pkg/agent/application/upgrade/artifact/download/headers_rtt_test.go b/internal/pkg/agent/application/upgrade/artifact/download/headers_rtt_test.go index 28fbf53b61e..9dfd1b252ae 100644 --- a/internal/pkg/agent/application/upgrade/artifact/download/headers_rtt_test.go +++ b/internal/pkg/agent/application/upgrade/artifact/download/headers_rtt_test.go @@ -6,7 +6,7 @@ package download import ( "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -31,7 +31,7 @@ func TestAddingHeaders(t *testing.T) { c.Transport = rtt resp, err := c.Get(server.URL) require.NoError(t, err) - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) defer resp.Body.Close() require.NoError(t, err) assert.Equal(t, b, msg) diff --git a/internal/pkg/agent/application/upgrade/artifact/download/http/downloader_test.go b/internal/pkg/agent/application/upgrade/artifact/download/http/downloader_test.go index d8c6e2a9304..2faf2159876 100644 --- a/internal/pkg/agent/application/upgrade/artifact/download/http/downloader_test.go +++ b/internal/pkg/agent/application/upgrade/artifact/download/http/downloader_test.go @@ -9,7 +9,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -36,7 +35,7 @@ import ( ) func TestDownload(t *testing.T) { - targetDir, err := ioutil.TempDir(os.TempDir(), "") + targetDir, err := os.MkdirTemp(os.TempDir(), "") if err != nil { t.Fatal(err) } @@ -98,7 +97,7 @@ func TestDownloadBodyError(t *testing.T) { defer srv.Close() client := srv.Client() - targetDir, err := ioutil.TempDir(os.TempDir(), "") + targetDir, err := os.MkdirTemp(os.TempDir(), "") if err != nil { t.Fatal(err) } @@ -152,7 +151,7 @@ func TestDownloadLogProgressWithLength(t *testing.T) { defer srv.Close() client := srv.Client() - targetDir, err := ioutil.TempDir(os.TempDir(), "") + targetDir, err := os.MkdirTemp(os.TempDir(), "") if err != nil { t.Fatal(err) } @@ -235,7 +234,7 @@ func TestDownloadLogProgressWithoutLength(t *testing.T) { defer srv.Close() client := srv.Client() - targetDir, err := ioutil.TempDir(os.TempDir(), "") + targetDir, err := os.MkdirTemp(os.TempDir(), "") if err != nil { t.Fatal(err) } diff --git a/internal/pkg/agent/application/upgrade/artifact/download/http/verifier.go b/internal/pkg/agent/application/upgrade/artifact/download/http/verifier.go index 5197f931285..587b968ff66 100644 --- a/internal/pkg/agent/application/upgrade/artifact/download/http/verifier.go +++ b/internal/pkg/agent/application/upgrade/artifact/download/http/verifier.go @@ -7,7 +7,7 @@ package http import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "os" @@ -182,5 +182,5 @@ func (v *Verifier) getPublicAsc(sourceURI string) ([]byte, error) { return nil, errors.New(fmt.Sprintf("call to '%s' returned unsuccessful status code: %d", sourceURI, resp.StatusCode), errors.TypeNetwork, errors.M(errors.MetaKeyURI, sourceURI)) } - return ioutil.ReadAll(resp.Body) + return io.ReadAll(resp.Body) } diff --git a/internal/pkg/agent/application/upgrade/artifact/download/verifier.go b/internal/pkg/agent/application/upgrade/artifact/download/verifier.go index e466c0119ea..991ab9ce16c 100644 --- a/internal/pkg/agent/application/upgrade/artifact/download/verifier.go +++ b/internal/pkg/agent/application/upgrade/artifact/download/verifier.go @@ -12,7 +12,6 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -313,7 +312,7 @@ func fetchPgpFromURI(uri string, client HTTPClient) ([]byte, error) { return nil, errors.New(fmt.Sprintf("call to '%s' returned unsuccessful status code: %d", uri, resp.StatusCode), errors.TypeNetwork, errors.M(errors.MetaKeyURI, uri)) } - return ioutil.ReadAll(resp.Body) + return io.ReadAll(resp.Body) } type HTTPClient interface { diff --git a/internal/pkg/agent/application/upgrade/step_mark.go b/internal/pkg/agent/application/upgrade/step_mark.go index bca67d307f0..90bc11dfda6 100644 --- a/internal/pkg/agent/application/upgrade/step_mark.go +++ b/internal/pkg/agent/application/upgrade/step_mark.go @@ -6,7 +6,6 @@ package upgrade import ( "context" - "io/ioutil" "os" "path/filepath" "time" @@ -129,7 +128,7 @@ func (u *Upgrader) markUpgrade(_ context.Context, log *logger.Logger, hash strin markerPath := markerFilePath() log.Infow("Writing upgrade marker file", "file.path", markerPath, "hash", marker.Hash, "prev_hash", prevHash) - if err := ioutil.WriteFile(markerPath, markerBytes, 0600); err != nil { + if err := os.WriteFile(markerPath, markerBytes, 0600); err != nil { return errors.New(err, errors.TypeFilesystem, "failed to create update marker file", errors.M(errors.MetaKeyPath, markerPath)) } @@ -144,7 +143,7 @@ func (u *Upgrader) markUpgrade(_ context.Context, log *logger.Logger, hash strin func UpdateActiveCommit(log *logger.Logger, hash string) error { activeCommitPath := filepath.Join(paths.Top(), agentCommitFile) log.Infow("Updating active commit", "file.path", activeCommitPath, "hash", hash) - if err := ioutil.WriteFile(activeCommitPath, []byte(hash), 0600); err != nil { + if err := os.WriteFile(activeCommitPath, []byte(hash), 0600); err != nil { return errors.New(err, errors.TypeFilesystem, "failed to update active commit", errors.M(errors.MetaKeyPath, activeCommitPath)) } diff --git a/internal/pkg/agent/application/upgrade/upgrade_test.go b/internal/pkg/agent/application/upgrade/upgrade_test.go index d0e3f756ab4..57230fdedbe 100644 --- a/internal/pkg/agent/application/upgrade/upgrade_test.go +++ b/internal/pkg/agent/application/upgrade/upgrade_test.go @@ -8,7 +8,6 @@ import ( "context" "crypto/tls" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -112,7 +111,7 @@ func Test_CopyFile(t *testing.T) { func TestShutdownCallback(t *testing.T) { l, _ := logger.New("test", false) - tmpDir, err := ioutil.TempDir("", "shutdown-test-") + tmpDir, err := os.MkdirTemp("", "shutdown-test-") require.NoError(t, err) defer os.RemoveAll(tmpDir) @@ -135,14 +134,14 @@ func TestShutdownCallback(t *testing.T) { cb := shutdownCallback(l, homePath, sourceVersion, targetVersion, newCommit) oldFilename := filepath.Join(sourceDir, filename) - err = ioutil.WriteFile(oldFilename, content, 0640) + err = os.WriteFile(oldFilename, content, 0640) require.NoError(t, err, "preparing file failed") err = cb() require.NoError(t, err, "callback failed") newFilename := filepath.Join(targetDir, filename) - newContent, err := ioutil.ReadFile(newFilename) + newContent, err := os.ReadFile(newFilename) require.NoError(t, err, "reading file failed") require.Equal(t, content, newContent, "contents are not equal") } diff --git a/internal/pkg/agent/cleaner/cleaner_test.go b/internal/pkg/agent/cleaner/cleaner_test.go index cf189b784d3..f242f8fc257 100644 --- a/internal/pkg/agent/cleaner/cleaner_test.go +++ b/internal/pkg/agent/cleaner/cleaner_test.go @@ -6,7 +6,6 @@ package cleaner import ( "context" - "io/ioutil" "os" "path/filepath" "testing" @@ -31,14 +30,14 @@ func TestCleaner(t *testing.T) { checkDir(t, dir, 0) // Create files - err := ioutil.WriteFile(watchFilePath, []byte{}, 0600) + err := os.WriteFile(watchFilePath, []byte{}, 0600) if err != nil { t.Fatal(err) } for i, fn := range removeFiles { removeFilePaths[i] = filepath.Join(dir, fn) - err := ioutil.WriteFile(removeFilePaths[i], []byte{}, 0600) + err := os.WriteFile(removeFilePaths[i], []byte{}, 0600) if err != nil { t.Fatal(err) } diff --git a/internal/pkg/agent/cmd/common.go b/internal/pkg/agent/cmd/common.go index f3a00be5cd5..7f106ab9e92 100644 --- a/internal/pkg/agent/cmd/common.go +++ b/internal/pkg/agent/cmd/common.go @@ -42,7 +42,7 @@ func NewCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Command { } // Init version information contained in package version file - err := version.InitVersionInformation() + err := version.InitVersionError() if err != nil { cmd.PrintErrf("Error initializing version information: %v\n", err) } diff --git a/internal/pkg/agent/cmd/component_spec.go b/internal/pkg/agent/cmd/component_spec.go index 1025e488b42..96eebeb123a 100644 --- a/internal/pkg/agent/cmd/component_spec.go +++ b/internal/pkg/agent/cmd/component_spec.go @@ -6,7 +6,7 @@ package cmd import ( "fmt" - "io/ioutil" + "os" "github.com/spf13/cobra" @@ -22,7 +22,7 @@ func newComponentSpecCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra. Long: "Validates a component specification that instructs the Elastic Agent how it should be ran.", Args: cobra.ExactArgs(1), RunE: func(c *cobra.Command, args []string) error { - data, err := ioutil.ReadFile(args[0]) + data, err := os.ReadFile(args[0]) if err != nil { return err } diff --git a/internal/pkg/agent/cmd/inspect.go b/internal/pkg/agent/cmd/inspect.go index 094d4584a06..24f1cc0bc79 100644 --- a/internal/pkg/agent/cmd/inspect.go +++ b/internal/pkg/agent/cmd/inspect.go @@ -130,20 +130,23 @@ type inspectConfigOpts struct { func inspectConfig(ctx context.Context, cfgPath string, opts inspectConfigOpts, streams *cli.IOStreams) error { l, err := newErrorLogger() if err != nil { - return err + return fmt.Errorf("error creating logger: %w", err) } if !opts.variables && !opts.includeMonitoring { fullCfg, err := operations.LoadFullAgentConfig(ctx, l, cfgPath, true) if err != nil { - return err + return fmt.Errorf("error loading agent config: %w", err) + } + err = printConfig(fullCfg, streams) + if err != nil { + return fmt.Errorf("error printing config: %w", err) } - return printConfig(fullCfg, streams) } cfg, lvl, err := getConfigWithVariables(ctx, l, cfgPath, opts.variablesWait) if err != nil { - return err + return fmt.Errorf("error fetching config with variables: %w", err) } agentInfo, err := info.NewAgentInfoWithLog(ctx, "error", false) @@ -212,12 +215,17 @@ func printMapStringConfig(mapStr map[string]interface{}, streams *cli.IOStreams) return err } +// convert the config object to a mapstr and print to the stream specified in in streams.Out func printConfig(cfg *config.Config, streams *cli.IOStreams) error { mapStr, err := cfg.ToMapStr() if err != nil { - return err + return fmt.Errorf("error parsing config as hashmap: %w", err) + } + err = printMapStringConfig(mapStr, streams) + if err != nil { + return fmt.Errorf("error printing config to output: %w", err) } - return printMapStringConfig(mapStr, streams) + return nil } type inspectComponentsOpts struct { diff --git a/internal/pkg/agent/cmd/install.go b/internal/pkg/agent/cmd/install.go index 7a5ee5cacc9..7b4c40e7a27 100644 --- a/internal/pkg/agent/cmd/install.go +++ b/internal/pkg/agent/cmd/install.go @@ -14,10 +14,12 @@ import ( "github.com/spf13/cobra" + "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent/internal/pkg/agent/application/filelock" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" "github.com/elastic/elastic-agent/internal/pkg/agent/install" "github.com/elastic/elastic-agent/internal/pkg/cli" + "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/elastic/elastic-agent/pkg/utils" ) @@ -54,7 +56,9 @@ would like the Agent to operate. } func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error { - err := validateEnrollFlags(cmd) + var err error + + err = validateEnrollFlags(cmd) if err != nil { return fmt.Errorf("could not validate flags: %w", err) } @@ -189,10 +193,34 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error { progBar := install.CreateAndStartNewSpinner(streams.Out, "Installing Elastic Agent...") + logCfg := logp.DefaultConfig(logp.DefaultEnvironment) + logCfg.Level = logp.DebugLevel + // Using in memory logger, so we don't write logs to the + // directory we are trying to delete + logp.ToObserverOutput()(&logCfg) + + err = logp.Configure(logCfg) + if err != nil { + return fmt.Errorf("error creating logging config: %w", err) + } + + log := logger.NewWithoutConfig("") + + defer func() { + if err == nil { + return + } + oLogs := logp.ObserverLogs().TakeAll() + fmt.Fprintf(os.Stderr, "Error uninstalling. Printing logs\n") + for _, oLog := range oLogs { + fmt.Fprintf(os.Stderr, "%v\n", oLog.Entry) + } + }() + var ownership utils.FileOwner cfgFile := paths.ConfigFile() if status != install.PackageInstall { - ownership, err = install.Install(cfgFile, topPath, unprivileged, progBar, streams) + ownership, err = install.Install(cfgFile, topPath, unprivileged, log, progBar, streams) if err != nil { return fmt.Errorf("error installing package: %w", err) } @@ -200,7 +228,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command) error { defer func() { if err != nil { progBar.Describe("Uninstalling") - innerErr := install.Uninstall(cfgFile, topPath, "", progBar) + innerErr := install.Uninstall(cfgFile, topPath, "", log, progBar) if innerErr != nil { progBar.Describe("Failed to Uninstall") } else { diff --git a/internal/pkg/agent/cmd/run.go b/internal/pkg/agent/cmd/run.go index 927a79808df..e878e75bb98 100644 --- a/internal/pkg/agent/cmd/run.go +++ b/internal/pkg/agent/cmd/run.go @@ -12,6 +12,7 @@ import ( "os/signal" "path/filepath" "strings" + "sync" "syscall" "time" @@ -19,6 +20,7 @@ import ( apmtransport "go.elastic.co/apm/transport" "gopkg.in/yaml.v2" + "github.com/hashicorp/go-multierror" "github.com/spf13/cobra" "github.com/elastic/elastic-agent-libs/api" @@ -61,6 +63,7 @@ const ( ) type cfgOverrider func(cfg *configuration.Configuration) +type awaiters []<-chan struct{} func newRunCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra.Command { cmd := &cobra.Command{ @@ -136,17 +139,38 @@ func run(override cfgOverrider, testingMode bool, fleetInitTimeout time.Duration go service.ProcessWindowsControlEvents(stopBeat) // detect otel - if runAsOtel := otel.IsOtelConfig(ctx, paths.ConfigFile()); runAsOtel { - return otel.Run(ctx, cancel, stop, testingMode) + runAsOtel := otel.IsOtelConfig(ctx, paths.ConfigFile()) + var awaiters awaiters + var resErr error + if runAsOtel { + var otelStartWg sync.WaitGroup + otelAwaiter := make(chan struct{}) + awaiters = append(awaiters, otelAwaiter) + + otelStartWg.Add(1) + go func() { + otelStartWg.Done() + if err := otel.Run(ctx, stop); err != nil { + resErr = multierror.Append(resErr, err) + } + + // close awaiter handled in run loop + close(otelAwaiter) + }() + + // wait for otel to start + otelStartWg.Wait() } - // not otel continue as usual - return runElasticAgent(ctx, cancel, override, stop, testingMode, fleetInitTimeout, modifiers...) + if err := runElasticAgent(ctx, cancel, override, stop, testingMode, fleetInitTimeout, runAsOtel, awaiters, modifiers...); err != nil { + resErr = multierror.Append(resErr, err) + } + return resErr } -func runElasticAgent(ctx context.Context, cancel context.CancelFunc, override cfgOverrider, stop chan bool, testingMode bool, fleetInitTimeout time.Duration, modifiers ...component.PlatformModifier) error { - cfg, err := loadConfig(ctx, override) +func runElasticAgent(ctx context.Context, cancel context.CancelFunc, override cfgOverrider, stop chan bool, testingMode bool, fleetInitTimeout time.Duration, runAsOtel bool, awaiters awaiters, modifiers ...component.PlatformModifier) error { + cfg, err := loadConfig(ctx, override, runAsOtel) if err != nil { return err } @@ -259,7 +283,7 @@ func runElasticAgent(ctx context.Context, cancel context.CancelFunc, override cf l.Info("APM instrumentation disabled") } - coord, configMgr, composable, err := application.New(ctx, l, baseLogger, logLvl, agentInfo, rex, tracer, testingMode, fleetInitTimeout, configuration.IsFleetServerBootstrap(cfg.Fleet), modifiers...) + coord, configMgr, composable, err := application.New(ctx, l, baseLogger, logLvl, agentInfo, rex, tracer, testingMode, fleetInitTimeout, configuration.IsFleetServerBootstrap(cfg.Fleet), runAsOtel, modifiers...) if err != nil { return err } @@ -366,6 +390,9 @@ LOOP: } cancel() err = <-appErr + for _, a := range awaiters { + <-a // wait for awaiter to be done + } if logShutdown { l.Info("Shutting down completed.") @@ -376,7 +403,11 @@ LOOP: return err } -func loadConfig(ctx context.Context, override cfgOverrider) (*configuration.Configuration, error) { +func loadConfig(ctx context.Context, override cfgOverrider, runAsOtel bool) (*configuration.Configuration, error) { + if runAsOtel { + return configuration.DefaultConfiguration(), nil + } + pathConfigFile := paths.ConfigFile() rawConfig, err := config.LoadFile(pathConfigFile) if err != nil { @@ -527,7 +558,7 @@ func tryDelayEnroll(ctx context.Context, logger *logger.Logger, cfg *configurati errors.M("path", enrollPath))) } logger.Info("Successfully performed delayed enrollment of this Elastic Agent.") - return loadConfig(ctx, override) + return loadConfig(ctx, override, false) } func initTracer(agentName, version string, mcfg *monitoringCfg.MonitoringConfig) (*apm.Tracer, error) { diff --git a/internal/pkg/agent/cmd/uninstall.go b/internal/pkg/agent/cmd/uninstall.go index 34d07c51683..d14c2b51840 100644 --- a/internal/pkg/agent/cmd/uninstall.go +++ b/internal/pkg/agent/cmd/uninstall.go @@ -10,9 +10,11 @@ import ( "github.com/spf13/cobra" + "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" "github.com/elastic/elastic-agent/internal/pkg/agent/install" "github.com/elastic/elastic-agent/internal/pkg/cli" + "github.com/elastic/elastic-agent/pkg/core/logger" "github.com/elastic/elastic-agent/pkg/utils" ) @@ -39,6 +41,8 @@ Unless -f is used this command will ask confirmation before performing removal. } func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error { + var err error + isAdmin, err := utils.HasRoot() if err != nil { return fmt.Errorf("unable to perform command while checking for administrator rights, %w", err) @@ -81,7 +85,31 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command) error { progBar := install.CreateAndStartNewSpinner(streams.Out, "Uninstalling Elastic Agent...") - err = install.Uninstall(paths.ConfigFile(), paths.Top(), uninstallToken, progBar) + logCfg := logp.DefaultConfig(logp.DefaultEnvironment) + logCfg.Level = logp.DebugLevel + // Using in memory logger, so we don't write logs to the + // directory we are trying to delete + logp.ToObserverOutput()(&logCfg) + + err = logp.Configure(logCfg) + if err != nil { + return fmt.Errorf("error creating logging config: %w", err) + } + + log := logger.NewWithoutConfig("") + + defer func() { + if err == nil { + return + } + oLogs := logp.ObserverLogs().TakeAll() + fmt.Fprintf(os.Stderr, "Error uninstalling. Printing logs\n") + for _, oLog := range oLogs { + fmt.Fprintf(os.Stderr, "%v\n", oLog.Entry) + } + }() + + err = install.Uninstall(paths.ConfigFile(), paths.Top(), uninstallToken, log, progBar) if err != nil { progBar.Describe("Failed to uninstall agent") return fmt.Errorf("error uninstalling agent: %w", err) diff --git a/internal/pkg/agent/cmd/upgrade.go b/internal/pkg/agent/cmd/upgrade.go index 767560f873f..6c33fa43498 100644 --- a/internal/pkg/agent/cmd/upgrade.go +++ b/internal/pkg/agent/cmd/upgrade.go @@ -7,7 +7,6 @@ package cmd import ( "context" "fmt" - "io/ioutil" "os" "github.com/spf13/cobra" @@ -80,7 +79,7 @@ func upgradeCmd(streams *cli.IOStreams, cmd *cobra.Command, args []string) error // get local PGP pgpPath, _ := cmd.Flags().GetString(flagPGPBytesPath) if len(pgpPath) > 0 { - content, err := ioutil.ReadFile(pgpPath) + content, err := os.ReadFile(pgpPath) if err != nil { return errors.New(err, "failed to read pgp file") } diff --git a/internal/pkg/agent/install/install.go b/internal/pkg/agent/install/install.go index bc5fa26a148..2ff0ef7dacc 100644 --- a/internal/pkg/agent/install/install.go +++ b/internal/pkg/agent/install/install.go @@ -16,6 +16,7 @@ import ( "github.com/otiai10/copy" "github.com/schollz/progressbar/v3" + "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" "github.com/elastic/elastic-agent/internal/pkg/agent/errors" "github.com/elastic/elastic-agent/internal/pkg/cli" @@ -30,7 +31,7 @@ const ( ) // Install installs Elastic Agent persistently on the system including creating and starting its service. -func Install(cfgFile, topPath string, unprivileged bool, pt *progressbar.ProgressBar, streams *cli.IOStreams) (utils.FileOwner, error) { +func Install(cfgFile, topPath string, unprivileged bool, log *logp.Logger, pt *progressbar.ProgressBar, streams *cli.IOStreams) (utils.FileOwner, error) { dir, err := findDirectory() if err != nil { return utils.FileOwner{}, errors.New(err, "failed to discover the source directory for installation", errors.TypeFilesystem) @@ -45,7 +46,7 @@ func Install(cfgFile, topPath string, unprivileged bool, pt *progressbar.Progres // Uninstall will fail on protected agent. // The protected Agent will need to be uninstalled first before it can be installed. pt.Describe("Uninstalling current Elastic Agent") - err = Uninstall(cfgFile, topPath, "", pt) + err = Uninstall(cfgFile, topPath, "", log, pt) if err != nil { pt.Describe("Failed to uninstall current Elastic Agent") return utils.FileOwner{}, errors.New( diff --git a/internal/pkg/agent/install/uninstall.go b/internal/pkg/agent/install/uninstall.go index 8f2234d0f4d..216ee898035 100644 --- a/internal/pkg/agent/install/uninstall.go +++ b/internal/pkg/agent/install/uninstall.go @@ -33,7 +33,15 @@ import ( ) // Uninstall uninstalls persistently Elastic Agent on the system. -func Uninstall(cfgFile, topPath, uninstallToken string, pt *progressbar.ProgressBar) error { +func Uninstall(cfgFile, topPath, uninstallToken string, log *logp.Logger, pt *progressbar.ProgressBar) error { + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("unable to get current working directory") + } + + if runtime.GOOS == "windows" && paths.HasPrefix(cwd, topPath) { + return fmt.Errorf("uninstall must be run from outside the installed path '%s'", topPath) + } // uninstall the current service // not creating the service, so no need to set the username and group to any value svc, err := newService(topPath) @@ -61,7 +69,7 @@ func Uninstall(cfgFile, topPath, uninstallToken string, pt *progressbar.Progress } // Uninstall components first - if err := uninstallComponents(context.Background(), cfgFile, uninstallToken, pt); err != nil { + if err := uninstallComponents(context.Background(), cfgFile, uninstallToken, log, pt); err != nil { // If service status was running it was stopped to uninstall the components. // If the components uninstall failed start the service again if status == service.StatusRunning { @@ -180,11 +188,7 @@ func containsString(str string, a []string, caseSensitive bool) bool { return false } -func uninstallComponents(ctx context.Context, cfgFile string, uninstallToken string, pt *progressbar.ProgressBar) error { - log, err := logger.NewWithLogpLevel("", logp.ErrorLevel, false) - if err != nil { - return fmt.Errorf("error creating logger: %w", err) - } +func uninstallComponents(ctx context.Context, cfgFile string, uninstallToken string, log *logp.Logger, pt *progressbar.ProgressBar) error { platform, err := component.LoadPlatformDetail() if err != nil { @@ -217,7 +221,7 @@ func uninstallComponents(ctx context.Context, cfgFile string, uninstallToken str } // Need to read the features from config on uninstall, in order to set the tamper protection feature flag correctly - if err := features.Apply(cfg); err != nil { + if err = features.Apply(cfg); err != nil { return fmt.Errorf("could not parse and apply feature flags config: %w", err) } @@ -234,7 +238,7 @@ func uninstallComponents(ctx context.Context, cfgFile string, uninstallToken str // This component is not active continue } - if err := uninstallServiceComponent(ctx, log, comp, uninstallToken, pt); err != nil { + if err = uninstallServiceComponent(ctx, log, comp, uninstallToken, pt); err != nil { os.Stderr.WriteString(fmt.Sprintf("failed to uninstall component %q: %s\n", comp.ID, err)) // The decision was made to change the behaviour and leave the Agent installed if Endpoint uninstall fails // https://github.com/elastic/elastic-agent/pull/2708#issuecomment-1574251911 diff --git a/internal/pkg/agent/storage/encrypted_disk_storage_windows_linux_test.go b/internal/pkg/agent/storage/encrypted_disk_storage_windows_linux_test.go index c29c7ec8fd9..83d0106d308 100644 --- a/internal/pkg/agent/storage/encrypted_disk_storage_windows_linux_test.go +++ b/internal/pkg/agent/storage/encrypted_disk_storage_windows_linux_test.go @@ -10,8 +10,8 @@ import ( "bytes" "context" "errors" + "io" "io/fs" - "io/ioutil" "os" "path/filepath" "testing" @@ -42,7 +42,7 @@ func TestEncryptedDiskStorageWindowsLinuxLoad(t *testing.T) { } defer r.Close() - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -99,7 +99,7 @@ func TestEncryptedDiskStorageWindowsLinuxLoad(t *testing.T) { } defer nr.Close() - b, err = ioutil.ReadAll(nr) + b, err = io.ReadAll(nr) if err != nil { t.Fatal(err) } diff --git a/internal/pkg/agent/storage/replace_store.go b/internal/pkg/agent/storage/replace_store.go index 5c166613d9f..fa495f9dc1e 100644 --- a/internal/pkg/agent/storage/replace_store.go +++ b/internal/pkg/agent/storage/replace_store.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "time" @@ -43,7 +42,7 @@ func NewReplaceOnSuccessStore(target string, replaceWith []byte, wrapped Store) // Save will replace a target file with new content if the wrapped store is successful. func (r *ReplaceOnSuccessStore) Save(in io.Reader) error { // Ensure we can read the target files before delegating any call to the wrapped store. - target, err := ioutil.ReadFile(r.target) + target, err := os.ReadFile(r.target) if err != nil { return errors.New(err, fmt.Sprintf("fail to read content of %s", r.target), diff --git a/internal/pkg/agent/storage/storage_test.go b/internal/pkg/agent/storage/storage_test.go index 52cd1960b22..98f11a772e0 100644 --- a/internal/pkg/agent/storage/storage_test.go +++ b/internal/pkg/agent/storage/storage_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "os" "path/filepath" "runtime" @@ -45,7 +44,7 @@ func TestReplaceOrRollbackStore(t *testing.T) { err = s.Save(in) require.NoError(t, err) - writtenContent, err := ioutil.ReadFile(target) + writtenContent, err := os.ReadFile(target) require.NoError(t, err) require.True(t, bytes.Equal(writtenContent, replaceWith)) @@ -70,7 +69,7 @@ func TestReplaceOrRollbackStore(t *testing.T) { err = s.Save(in) require.Error(t, err) - writtenContent, err := ioutil.ReadFile(target) + writtenContent, err := os.ReadFile(target) require.NoError(t, err) require.True(t, bytes.Equal(writtenContent, oldContent)) @@ -94,7 +93,7 @@ func TestReplaceOrRollbackStore(t *testing.T) { err = s.Save(in) require.Error(t, err) - writtenContent, err := ioutil.ReadFile(target) + writtenContent, err := os.ReadFile(target) require.NoError(t, err) require.True(t, bytes.Equal(writtenContent, replaceWith)) @@ -124,7 +123,7 @@ func TestDiskStore(t *testing.T) { err = d.Save(bytes.NewReader(msg)) require.NoError(t, err) - content, err := ioutil.ReadFile(target) + content, err := os.ReadFile(target) require.NoError(t, err) require.Equal(t, msg, content) @@ -132,7 +131,7 @@ func TestDiskStore(t *testing.T) { }) t.Run("when the target do no exist", func(t *testing.T) { - dir, err := ioutil.TempDir("", "configs") + dir, err := os.MkdirTemp("", "configs") require.NoError(t, err) defer os.Remove(dir) @@ -143,7 +142,7 @@ func TestDiskStore(t *testing.T) { err = d.Save(bytes.NewReader(msg)) require.NoError(t, err) - content, err := ioutil.ReadFile(target) + content, err := os.ReadFile(target) require.NoError(t, err) require.Equal(t, msg, content) @@ -160,7 +159,7 @@ func TestDiskStore(t *testing.T) { require.NoError(t, err) defer r.Close() - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, msg, content) checkPerms(t, target, perms) @@ -168,12 +167,12 @@ func TestDiskStore(t *testing.T) { } func genFile(b []byte) (string, error) { - dir, err := ioutil.TempDir("", "configs") + dir, err := os.MkdirTemp("", "configs") if err != nil { return "", err } - f, err := ioutil.TempFile(dir, "config-") + f, err := os.CreateTemp(dir, "config-") if err != nil { return "", err } @@ -187,7 +186,7 @@ func genFile(b []byte) (string, error) { } func requireFilesCount(t *testing.T, dir string, l int) { - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) require.NoError(t, err) require.Equal(t, l, len(files)) } diff --git a/internal/pkg/agent/storage/store/action_store_test.go b/internal/pkg/agent/storage/store/action_store_test.go index e193183ab22..5a5d56b8056 100644 --- a/internal/pkg/agent/storage/store/action_store_test.go +++ b/internal/pkg/agent/storage/store/action_store_test.go @@ -5,7 +5,6 @@ package store import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -21,7 +20,7 @@ func TestActionStore(t *testing.T) { log, _ := logger.New("action_store", false) withFile := func(fn func(t *testing.T, file string)) func(*testing.T) { return func(t *testing.T) { - dir, err := ioutil.TempDir("", "action-store") + dir, err := os.MkdirTemp("", "action-store") require.NoError(t, err) defer os.RemoveAll(dir) file := filepath.Join(dir, "config.yml") diff --git a/internal/pkg/agent/vault/seed.go b/internal/pkg/agent/vault/seed.go index 6112e48313e..50c96a4a715 100644 --- a/internal/pkg/agent/vault/seed.go +++ b/internal/pkg/agent/vault/seed.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io/fs" - "io/ioutil" "os" "path/filepath" "sync" @@ -32,7 +31,7 @@ func getSeed(path string) ([]byte, error) { mxSeed.Lock() defer mxSeed.Unlock() - b, err := ioutil.ReadFile(fp) + b, err := os.ReadFile(fp) if err != nil { return nil, fmt.Errorf("could not read seed file: %w", err) } @@ -50,7 +49,7 @@ func createSeedIfNotExists(path string) ([]byte, error) { mxSeed.Lock() defer mxSeed.Unlock() - b, err := ioutil.ReadFile(fp) + b, err := os.ReadFile(fp) if err != nil { if !errors.Is(err, os.ErrNotExist) { return nil, err @@ -66,7 +65,7 @@ func createSeedIfNotExists(path string) ([]byte, error) { return nil, err } - err = ioutil.WriteFile(fp, seed, 0600) + err = os.WriteFile(fp, seed, 0600) if err != nil { return nil, err } diff --git a/internal/pkg/basecmd/version/cmd_test.go b/internal/pkg/basecmd/version/cmd_test.go index 2959c576183..93ed88101e2 100644 --- a/internal/pkg/basecmd/version/cmd_test.go +++ b/internal/pkg/basecmd/version/cmd_test.go @@ -5,7 +5,7 @@ package version import ( - "io/ioutil" + "io" "strings" "testing" @@ -30,7 +30,7 @@ func TestCmdBinaryOnly(t *testing.T) { require.NoError(t, err) err = cmd.Execute() require.NoError(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) assert.True(t, strings.Contains(string(version), "Binary: ")) @@ -46,7 +46,7 @@ func TestCmdBinaryOnlyYAML(t *testing.T) { require.NoError(t, err) err = cmd.Execute() require.NoError(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) @@ -67,7 +67,7 @@ func TestCmdDaemon(t *testing.T) { cmd := NewCommandWithArgs(streams) err := cmd.Execute() require.NoError(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) assert.True(t, strings.Contains(string(version), "Binary: ")) @@ -85,7 +85,7 @@ func TestCmdDaemonYAML(t *testing.T) { require.NoError(t, err) err = cmd.Execute() require.NoError(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) @@ -103,7 +103,7 @@ func TestCmdDaemonErr(t *testing.T) { cmd := NewCommandWithArgs(streams) err := cmd.Execute() require.Error(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) assert.True(t, strings.Contains(string(version), "Binary: ")) @@ -118,7 +118,7 @@ func TestCmdDaemonErrYAML(t *testing.T) { require.NoError(t, err) err = cmd.Execute() require.Error(t, err) - version, err := ioutil.ReadAll(out) + version, err := io.ReadAll(out) require.NoError(t, err) var output Output diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index d9b5d956618..0f0f9a53dea 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -7,7 +7,6 @@ package config import ( "fmt" "io" - "io/ioutil" "os" "gopkg.in/yaml.v2" @@ -74,7 +73,7 @@ func NewConfigFrom(from interface{}, opts ...interface{}) (*Config, error) { if closer, ok := from.(io.Closer); ok { defer closer.Close() } - fData, err := ioutil.ReadAll(in) + fData, err := io.ReadAll(in) if err != nil { return nil, err } @@ -156,7 +155,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { } ucfgOpts, local, err := getOptions(opts...) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking logs: %w", err) } // remove and unpack each skip keys into its own map with no resolve @@ -167,21 +166,21 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { if c.access().HasField(skip) { subCfg, err := c.access().Child(skip, -1) if err != nil { - return nil, err + return nil, fmt.Errorf("error accessing skip key %s: %w", skip, err) } var subUnpacked interface{} if subCfg.IsDict() { var subDict map[string]interface{} err = subCfg.Unpack(&subDict, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking subdict object in config for skip key %s: %w", skip, err) } subUnpacked = subDict } else if subCfg.IsArray() { var subArr []interface{} err = subCfg.Unpack(&subArr, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking subarray in config for skip key %s: %w ", skip, err) } subUnpacked = subArr } else { @@ -189,7 +188,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { } _, err = c.access().Remove(skip, -1) if err != nil { - return nil, err + return nil, fmt.Errorf("error removing skip key %s: %w", skip, err) } skippedKeys[skip] = subUnpacked skippedKeysOrig[skip] = subCfg @@ -199,7 +198,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { // perform unpack with the skip keys removed var m map[string]interface{} if err := c.access().Unpack(&m, ucfgOpts...); err != nil { - return nil, err + return nil, fmt.Errorf("error unpacking config to MapStr object: %w", err) } // add the skipped keys into the map and back into the config @@ -209,7 +208,7 @@ func (c *Config) ToMapStr(opts ...interface{}) (map[string]interface{}, error) { if len(skippedKeysOrig) > 0 { err := c.access().Merge(skippedKeysOrig, ucfg.ResolveNOOP) if err != nil { - return nil, err + return nil, fmt.Errorf("error merging config with skipped key config: %w", err) } } return m, nil diff --git a/internal/pkg/config/operations/inspector.go b/internal/pkg/config/operations/inspector.go index f1066c22531..55e78069292 100644 --- a/internal/pkg/config/operations/inspector.go +++ b/internal/pkg/config/operations/inspector.go @@ -29,12 +29,12 @@ var ( func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath string, failOnFleetMissing bool) (*config.Config, error) { rawConfig, err := loadConfig(ctx, cfgPath) if err != nil { - return nil, err + return nil, fmt.Errorf("error loading raw config: %w", err) } cfg, err := configuration.NewFromConfig(rawConfig) if err != nil { - return nil, err + return nil, fmt.Errorf("error creating config object from raw agent config: %w", err) } if configuration.IsStandalone(cfg.Fleet) { @@ -57,7 +57,7 @@ func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath str fleetConfig, err := loadFleetConfig(ctx, logger) if err != nil { - return nil, err + return nil, fmt.Errorf("error obtaining fleet config: %w", err) } else if fleetConfig == nil { if failOnFleetMissing { return nil, ErrNoFleetConfig @@ -78,7 +78,7 @@ func LoadFullAgentConfig(ctx context.Context, logger *logger.Logger, cfgPath str func loadConfig(ctx context.Context, configPath string) (*config.Config, error) { rawConfig, err := config.LoadFile(configPath) if err != nil { - return nil, err + return nil, fmt.Errorf("error loading config file %s: %w", configPath, err) } path := paths.AgentConfigFile() @@ -100,10 +100,13 @@ func loadConfig(ctx context.Context, configPath string) (*config.Config, error) } // merge local configuration and configuration persisted from fleet. - _ = rawConfig.Merge(config) + err = rawConfig.Merge(config) + if err != nil { + return nil, fmt.Errorf("error merging local and fleet config: %w", err) + } if err := info.InjectAgentConfig(rawConfig); err != nil { - return nil, err + return nil, fmt.Errorf("error injecting agent config: %w", err) } return rawConfig, nil diff --git a/internal/pkg/crypto/io_test.go b/internal/pkg/crypto/io_test.go index 1e3bd24685f..57daafe4bf2 100644 --- a/internal/pkg/crypto/io_test.go +++ b/internal/pkg/crypto/io_test.go @@ -8,7 +8,6 @@ import ( "bufio" "bytes" "io" - "io/ioutil" "testing" "github.com/stretchr/testify/require" @@ -34,7 +33,7 @@ func TestIO(t *testing.T) { r, err := NewReaderWithDefaults(dest, passwd) require.NoError(t, err) - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, msg, content) @@ -61,7 +60,7 @@ func TestIO(t *testing.T) { r, err := NewReaderWithDefaults(dest, passwd) require.NoError(t, err) - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, msg, content) @@ -86,7 +85,7 @@ func TestIO(t *testing.T) { r, err := NewReaderWithDefaults(dest, []byte("bad password")) require.NoError(t, err) - _, err = ioutil.ReadAll(r) + _, err = io.ReadAll(r) require.Error(t, err) }) @@ -115,7 +114,7 @@ func TestIO(t *testing.T) { r, err := NewReaderWithDefaults(dest, passwd) require.NoError(t, err) - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, msg, content) @@ -143,7 +142,7 @@ func TestIO(t *testing.T) { b := bufio.NewReaderSize(r, 100) - content, err := ioutil.ReadAll(b) + content, err := io.ReadAll(b) require.NoError(t, err) require.Equal(t, msg, content) @@ -159,7 +158,7 @@ func TestIO(t *testing.T) { b := bufio.NewReaderSize(r, 100) - _, err = ioutil.ReadAll(b) + _, err = io.ReadAll(b) require.Error(t, err) }) @@ -188,7 +187,7 @@ func TestIO(t *testing.T) { r, err := NewReaderWithDefaults(dest, passwd) require.NoError(t, err) - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) require.NoError(t, err) require.Equal(t, expected, content) diff --git a/internal/pkg/dir/discover_test.go b/internal/pkg/dir/discover_test.go index 153e94d0304..c4cc03a8c62 100644 --- a/internal/pkg/dir/discover_test.go +++ b/internal/pkg/dir/discover_test.go @@ -5,7 +5,6 @@ package dir import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -59,7 +58,7 @@ func TestDiscover(t *testing.T) { func withFiles(files []string, fn func(dst string, t *testing.T)) func(t *testing.T) { return func(t *testing.T) { - tmp, _ := ioutil.TempDir("", "watch") + tmp, _ := os.MkdirTemp("", "watch") defer os.RemoveAll(tmp) for _, file := range files { diff --git a/internal/pkg/filewatcher/watcher_test.go b/internal/pkg/filewatcher/watcher_test.go index 140376ca197..07dba632012 100644 --- a/internal/pkg/filewatcher/watcher_test.go +++ b/internal/pkg/filewatcher/watcher_test.go @@ -5,7 +5,6 @@ package filewatcher import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -24,7 +23,7 @@ func TestWatch(t *testing.T) { })) t.Run("newly added files are discovered", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -43,7 +42,7 @@ func TestWatch(t *testing.T) { })) t.Run("ignore old files", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -68,7 +67,7 @@ func TestWatch(t *testing.T) { })) t.Run("can unwatch a watched file", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -97,7 +96,7 @@ func TestWatch(t *testing.T) { w.Unwatch(path) // Add new content to the file. - ioutil.WriteFile(path, []byte("heeeelo"), 0644) + os.WriteFile(path, []byte("heeeelo"), 0644) // Should not find the file. r, u, err = w.scan() @@ -107,7 +106,7 @@ func TestWatch(t *testing.T) { })) t.Run("can returns the list of watched files", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -125,7 +124,7 @@ func TestWatch(t *testing.T) { })) t.Run("update returns updated, unchanged and watched files", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -184,7 +183,7 @@ func TestWatch(t *testing.T) { })) t.Run("should cleanup files that disapear", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) @@ -201,7 +200,7 @@ func TestWatch(t *testing.T) { })) t.Run("should allow to invalidate the cache ", withWatch(func(t *testing.T, w *Watch) { - tmp, err := ioutil.TempDir("", "watch") + tmp, err := os.MkdirTemp("", "watch") require.NoError(t, err) defer os.RemoveAll(tmp) diff --git a/internal/pkg/fleetapi/ack_cmd.go b/internal/pkg/fleetapi/ack_cmd.go index e5fe956753c..a12839dcb2d 100644 --- a/internal/pkg/fleetapi/ack_cmd.go +++ b/internal/pkg/fleetapi/ack_cmd.go @@ -9,7 +9,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "go.elastic.co/apm" @@ -124,7 +124,7 @@ func (e *AckCmd) Execute(ctx context.Context, r *AckRequest) (_ *AckResponse, er defer resp.Body.Close() // Read ack response always it can be sent with any status code. - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/internal/pkg/fleetapi/acker/fleet/fleet_acker_test.go b/internal/pkg/fleetapi/acker/fleet/fleet_acker_test.go index 6abe28fec72..fcde240fe34 100644 --- a/internal/pkg/fleetapi/acker/fleet/fleet_acker_test.go +++ b/internal/pkg/fleetapi/acker/fleet/fleet_acker_test.go @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "net/url" "testing" @@ -64,7 +63,7 @@ func wrapStrToResp(code int, body string) *http.Response { Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, - Body: ioutil.NopCloser(bytes.NewBufferString(body)), + Body: io.NopCloser(bytes.NewBufferString(body)), ContentLength: int64(len(body)), Header: make(http.Header), } diff --git a/internal/pkg/fleetapi/checkin_cmd.go b/internal/pkg/fleetapi/checkin_cmd.go index 4c14454ce18..6f407708b8b 100644 --- a/internal/pkg/fleetapi/checkin_cmd.go +++ b/internal/pkg/fleetapi/checkin_cmd.go @@ -9,7 +9,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "time" @@ -137,7 +137,7 @@ func (e *CheckinCmd) Execute(ctx context.Context, r *CheckinRequest) (*CheckinRe return nil, sendDuration, client.ExtractError(resp.Body) } - rs, err := ioutil.ReadAll(resp.Body) + rs, err := io.ReadAll(resp.Body) if err != nil { return nil, sendDuration, errors.New(err, "failed to read checkin response") } diff --git a/internal/pkg/fleetapi/checkin_cmd_test.go b/internal/pkg/fleetapi/checkin_cmd_test.go index 56726bb5559..46a0b4db4d1 100644 --- a/internal/pkg/fleetapi/checkin_cmd_test.go +++ b/internal/pkg/fleetapi/checkin_cmd_test.go @@ -8,7 +8,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "testing" "time" @@ -214,7 +214,7 @@ func TestCheckin(t *testing.T) { var req *Request - content, err := ioutil.ReadAll(r.Body) + content, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.NoError(t, json.Unmarshal(content, &req)) assert.Equal(t, "linux", req.Metadata.OS.Name) @@ -248,7 +248,7 @@ func TestCheckin(t *testing.T) { var req *Request - content, err := ioutil.ReadAll(r.Body) + content, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.NoError(t, json.Unmarshal(content, &req)) assert.Nil(t, req.Metadata) diff --git a/internal/pkg/fleetapi/client/client.go b/internal/pkg/fleetapi/client/client.go index b6c9f7584ef..cddd162726b 100644 --- a/internal/pkg/fleetapi/client/client.go +++ b/internal/pkg/fleetapi/client/client.go @@ -9,7 +9,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -100,7 +99,7 @@ func ExtractError(resp io.Reader) error { Message string `json:"message"` }{} - data, err := ioutil.ReadAll(resp) + data, err := io.ReadAll(resp) if err != nil { return errors.New(err, "fail to read original error") } diff --git a/internal/pkg/fleetapi/client/client_test.go b/internal/pkg/fleetapi/client/client_test.go index cc5d2501aa8..40be306bc80 100644 --- a/internal/pkg/fleetapi/client/client_test.go +++ b/internal/pkg/fleetapi/client/client_test.go @@ -7,7 +7,7 @@ package client import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -47,7 +47,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, "GET", "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, `{ message: "hello" }`, string(body)) @@ -104,7 +104,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, "GET", "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, `{ message: "hello" }`, string(body)) diff --git a/internal/pkg/otel/README.md b/internal/pkg/otel/README.md index c084e3f9677..8226da62513 100644 --- a/internal/pkg/otel/README.md +++ b/internal/pkg/otel/README.md @@ -27,8 +27,8 @@ This section provides a summary of components included in the Elastic Distributi | Component | Version | |---|---| -| filelogreceiver | v0.92.0| -| otlpreceiver | v0.92.0| +| filelogreceiver | v0.93.0| +| otlpreceiver | v0.93.0| @@ -37,9 +37,9 @@ This section provides a summary of components included in the Elastic Distributi | Component | Version | |---|---| -| fileexporter | v0.92.0| -| debugexporter | v0.92.0| -| otlpexporter | v0.92.0| +| fileexporter | v0.93.0| +| debugexporter | v0.93.0| +| otlpexporter | v0.93.0| @@ -48,11 +48,11 @@ This section provides a summary of components included in the Elastic Distributi | Component | Version | |---|---| -| attributesprocessor | v0.92.0| -| resourceprocessor | v0.92.0| -| transformprocessor | v0.92.0| -| batchprocessor | v0.92.0| -| memorylimiterprocessor | v0.92.0| +| attributesprocessor | v0.93.0| +| resourceprocessor | v0.93.0| +| transformprocessor | v0.93.0| +| batchprocessor | v0.93.0| +| memorylimiterprocessor | v0.93.0| diff --git a/internal/pkg/otel/config_manager.go b/internal/pkg/otel/config_manager.go new file mode 100644 index 00000000000..a9a90cab627 --- /dev/null +++ b/internal/pkg/otel/config_manager.go @@ -0,0 +1,47 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package otel + +import ( + "context" + + "github.com/elastic/elastic-agent/internal/pkg/agent/application/coordinator" +) + +// OtelModeConfigManager serves as a config manager for OTel use cases +// In this case agent should ignore all configuration coming from elastic-agent.yml file +// or other sources. +type OtelModeConfigManager struct { + ch chan coordinator.ConfigChange + errCh chan error +} + +// NewOtelModeConfigManager creates new OtelModeConfigManager ignoring +// configuration coming from other sources. +func NewOtelModeConfigManager() *OtelModeConfigManager { + return &OtelModeConfigManager{ + ch: make(chan coordinator.ConfigChange), + errCh: make(chan error), + } +} + +func (t *OtelModeConfigManager) Run(ctx context.Context) error { + <-ctx.Done() + return ctx.Err() +} + +func (t *OtelModeConfigManager) Errors() <-chan error { + return t.errCh +} + +// ActionErrors returns the error channel for actions. +// Returns nil channel. +func (t *OtelModeConfigManager) ActionErrors() <-chan error { + return nil +} + +func (t *OtelModeConfigManager) Watch() <-chan coordinator.ConfigChange { + return t.ch +} diff --git a/internal/pkg/otel/run.go b/internal/pkg/otel/run.go index ae2f4249823..833121221d0 100644 --- a/internal/pkg/otel/run.go +++ b/internal/pkg/otel/run.go @@ -43,7 +43,7 @@ func IsOtelConfig(ctx context.Context, pathConfigFile string) bool { return false } -func Run(ctx context.Context, cancel context.CancelFunc, stop chan bool, testingMode bool) error { +func Run(ctx context.Context, stop chan bool) error { fmt.Fprintln(os.Stdout, "Starting in otel mode") settings, err := newSettings(paths.ConfigFile(), release.Version()) if err != nil { diff --git a/internal/pkg/release/version.go b/internal/pkg/release/version.go index 93f78e5f4be..5b1036ab161 100644 --- a/internal/pkg/release/version.go +++ b/internal/pkg/release/version.go @@ -56,6 +56,15 @@ func Version() string { return version.GetAgentPackageVersion() } +// VersionWithSnapshot returns the version of the application. +func VersionWithSnapshot() string { + agentPackageVersion := version.GetAgentPackageVersion() + if Snapshot() { + agentPackageVersion += "-SNAPSHOT" + } + return agentPackageVersion +} + // Snapshot returns true if binary was built as snapshot. func Snapshot() bool { val, err := strconv.ParseBool(snapshot) diff --git a/internal/pkg/remote/client_test.go b/internal/pkg/remote/client_test.go index 892bd5099c5..696121395c8 100644 --- a/internal/pkg/remote/client_test.go +++ b/internal/pkg/remote/client_test.go @@ -8,7 +8,7 @@ import ( "bytes" "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -102,7 +102,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/nested/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -127,7 +127,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -231,7 +231,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -257,7 +257,7 @@ func TestHTTPClient(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -300,7 +300,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -331,7 +331,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/echo-hello", nil, nil, bytes.NewBuffer([]byte("hello"))) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) @@ -363,7 +363,7 @@ func TestHTTPClient(t *testing.T) { resp, err := client.Send(ctx, http.MethodGet, "/echo-hello", nil, nil, nil) require.NoError(t, err) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, successResp, string(body)) diff --git a/internal/pkg/remote/round_trippers.go b/internal/pkg/remote/round_trippers.go index e6583af57a8..76c3fec139e 100644 --- a/internal/pkg/remote/round_trippers.go +++ b/internal/pkg/remote/round_trippers.go @@ -8,7 +8,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "strings" "time" @@ -67,13 +67,13 @@ func (r *DebugRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) } if req.Body != nil { - dataReq, err := ioutil.ReadAll(req.Body) + dataReq, err := io.ReadAll(req.Body) if err != nil { return nil, errors.Wrap(err, "fail to read the body of the request") } req.Body.Close() - req.Body = ioutil.NopCloser(bytes.NewBuffer(dataReq)) + req.Body = io.NopCloser(bytes.NewBuffer(dataReq)) b.WriteString("Request Body:\n") b.WriteString(string(prettyBody(dataReq)) + "\n") @@ -101,7 +101,7 @@ func (r *DebugRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) } // Hijack the body and output it in the log, this is only for debugging and development. - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) if err != nil { return resp, errors.Wrap(err, "fail to read the body of the response") } @@ -110,7 +110,7 @@ func (r *DebugRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) b.WriteString("Response Body:\n") b.WriteString(string(prettyBody(data)) + "\n") - resp.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + resp.Body = io.NopCloser(bytes.NewBuffer(data)) r.log.Debug(b.String()) diff --git a/pkg/api/v1/api.go b/pkg/api/v1/api.go new file mode 100644 index 00000000000..c7ed6a26cf9 --- /dev/null +++ b/pkg/api/v1/api.go @@ -0,0 +1,13 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// Package v1 contains definitions for elastic-agent/v1 objects +package v1 + +const VERSION = "co.elastic.agent/v1" + +type apiObject struct { + Version string `yaml:"version" json:"version"` + Kind string `yaml:"kind" json:"kind"` +} diff --git a/pkg/api/v1/manifest.go b/pkg/api/v1/manifest.go new file mode 100644 index 00000000000..bc103b46e32 --- /dev/null +++ b/pkg/api/v1/manifest.go @@ -0,0 +1,45 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package v1 + +import ( + "fmt" + "io" + + "gopkg.in/yaml.v2" +) + +const ManifestKind = "PackageManifest" + +type PackageDesc struct { + Version string `yaml:"version,omitempty" json:"version,omitempty"` + Snapshot bool `yaml:"snapshot,omitempty" json:"snapshot,omitempty"` + VersionedHome string `yaml:"versioned-home,omitempty" json:"versionedHome,omitempty"` + PathMappings []map[string]string `yaml:"path-mappings,omitempty" json:"pathMappings,omitempty"` +} + +type PackageManifest struct { + apiObject `yaml:",inline"` + Package PackageDesc `yaml:"package" json:"package"` +} + +func NewManifest() *PackageManifest { + return &PackageManifest{ + apiObject: apiObject{ + Version: VERSION, + Kind: ManifestKind, + }, + } +} + +func ParseManifest(r io.Reader) (*PackageManifest, error) { + m := new(PackageManifest) + err := yaml.NewDecoder(r).Decode(m) + if err != nil { + return nil, fmt.Errorf("decoding package manifest: %w", err) + } + + return m, nil +} diff --git a/pkg/api/v1/manifest_test.go b/pkg/api/v1/manifest_test.go new file mode 100644 index 00000000000..2466c4501e7 --- /dev/null +++ b/pkg/api/v1/manifest_test.go @@ -0,0 +1,49 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package v1 + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEmptyManifest(t *testing.T) { + m := NewManifest() + assert.Equal(t, VERSION, m.Version) + assert.Equal(t, ManifestKind, m.Kind) +} + +func TestParseManifest(t *testing.T) { + + manifest := ` +# version and kind to uniquely identify the schema +version: co.elastic.agent/v1 +kind: PackageManifest + +# description of the package itself +package: + version: 8.12.0 + snapshot: false + versioned-home: data/elastic-agent-4f2d39/ + # generic path mapping: + # - key is a prefix representing a path relative to the top of the archive + # - value is the substitution to be applied when extracting the files + path-mappings: + - data/elastic-agent-4f2d39/ : data/elastic-agent-8.12.0/ + foo: bar + - manifest.yaml : data/elastic-agent-8.12.0/manifest.yaml +` + m, err := ParseManifest(strings.NewReader(manifest)) + assert.NoError(t, err) + assert.Equal(t, VERSION, m.Version) + assert.Equal(t, ManifestKind, m.Kind) + + assert.Equal(t, m.Package.Version, "8.12.0") + assert.Equal(t, m.Package.Snapshot, false) + assert.Equal(t, m.Package.VersionedHome, "data/elastic-agent-4f2d39/") + assert.Equal(t, m.Package.PathMappings, []map[string]string{{"data/elastic-agent-4f2d39/": "data/elastic-agent-8.12.0/", "foo": "bar"}, {"manifest.yaml": "data/elastic-agent-8.12.0/manifest.yaml"}}) +} diff --git a/pkg/component/component_test.go b/pkg/component/component_test.go index 8d42ab64427..b6b49546fce 100644 --- a/pkg/component/component_test.go +++ b/pkg/component/component_test.go @@ -445,7 +445,7 @@ func TestToComponents(t *testing.T) { OutputType: "elasticsearch", ID: "endpoint-default", InputSpec: &InputRuntimeSpec{}, - Err: NewErrInputRuntimeCheckFail("No support for RHEL7 on arm64"), + Err: NewErrInputRuntimeCheckFail("Elastic Defend doesn't support RHEL7 on arm64"), Units: []Unit{ { ID: "endpoint-default", diff --git a/pkg/component/load.go b/pkg/component/load.go index 021b42dbb43..39343842dc5 100644 --- a/pkg/component/load.go +++ b/pkg/component/load.go @@ -7,7 +7,6 @@ package component import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" @@ -196,7 +195,7 @@ func specFilesForDirectory(dir string) (map[string]Spec, error) { return nil, err } for _, match := range matches { - data, err := ioutil.ReadFile(match) + data, err := os.ReadFile(match) if err != nil { return nil, fmt.Errorf("failed reading spec %s: %w", match, err) } diff --git a/pkg/component/load_test.go b/pkg/component/load_test.go index 91a6d1a1be6..1bc4bed8915 100644 --- a/pkg/component/load_test.go +++ b/pkg/component/load_test.go @@ -5,7 +5,7 @@ package component import ( - "io/ioutil" + "os" "path/filepath" "testing" @@ -97,7 +97,7 @@ func TestLoadSpec_Components(t *testing.T) { for _, scenario := range scenarios { t.Run(scenario.Name, func(t *testing.T) { - data, err := ioutil.ReadFile(filepath.Join("..", "..", "specs", scenario.Path)) + data, err := os.ReadFile(filepath.Join("..", "..", "specs", scenario.Path)) require.NoError(t, err) _, err = LoadSpec(data) require.NoError(t, err) diff --git a/pkg/component/runtime/manager_fake_input_test.go b/pkg/component/runtime/manager_fake_input_test.go index 06fb41860b2..5a61fcde1ac 100644 --- a/pkg/component/runtime/manager_fake_input_test.go +++ b/pkg/component/runtime/manager_fake_input_test.go @@ -1307,35 +1307,11 @@ LOOP: require.Equal(t, context.Canceled, err, "Run should return with context canceled, got %v", err.Error()) } -func (suite *FakeInputSuite) TestManager_NoDeadlock() { - t := suite.T() - // NOTE: This is a long-running test that spams the runtime managers `Update` function to try and - // trigger a deadlock. This test takes 2 minutes to run trying to re-produce issue: - // https://github.com/elastic/elastic-agent/issues/2691 - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - ai, _ := info.NewAgentInfo(ctx, true) - m, err := NewManager(newDebugLogger(t), newDebugLogger(t), "localhost:0", ai, apmtest.DiscardTracer, newTestMonitoringMgr(), configuration.DefaultGRPCConfig()) - require.NoError(t, err) - errCh := make(chan error) - go func() { - err := m.Run(ctx) - if errors.Is(err, context.Canceled) { - err = nil - } - errCh <- err - }() - - waitCtx, waitCancel := context.WithTimeout(ctx, 1*time.Second) - defer waitCancel() - if err := waitForReady(waitCtx, m); err != nil { - require.NoError(t, err) - } - +// A component that can be fed to Manager.Update, with an index to allow +// looping with distinct configurations at each step. +func noDeadlockTestComponent(t *testing.T, index int) component.Component { binaryPath := testBinary(t, "component") - comp := component.Component{ + return component.Component{ ID: "fake-default", InputSpec: &component.InputRuntimeSpec{ InputType: "fake", @@ -1351,99 +1327,92 @@ func (suite *FakeInputSuite) TestManager_NoDeadlock() { Config: component.MustExpectedConfig(map[string]interface{}{ "type": "fake", "state": int(client.UnitStateHealthy), - "message": "Fake Healthy", + "message": fmt.Sprintf("Fake Healthy %d", index), }), }, }, } +} - updatedCh := make(chan time.Time) - updatedErr := make(chan error) - updatedCtx, updatedCancel := context.WithCancel(context.Background()) - defer updatedCancel() +func (suite *FakeInputSuite) TestManager_NoDeadlock() { + t := suite.T() + // NOTE: This is a long-running test that spams the runtime managers `Update` function to try and + // trigger a deadlock. This test takes 2 minutes to run trying to re-produce issue: + // https://github.com/elastic/elastic-agent/issues/2691 + + // How long to run the test + testDuration := 2 * time.Minute + + // How long without an update before we report it as a deadlock + maxUpdateInterval := 15 * time.Second + + // Create the runtime manager + ai, _ := info.NewAgentInfo(context.Background(), true) + m, err := NewManager(newDebugLogger(t), newDebugLogger(t), "localhost:0", ai, apmtest.DiscardTracer, newTestMonitoringMgr(), configuration.DefaultGRPCConfig()) + require.NoError(t, err) + + // Start the runtime manager in a goroutine, passing its termination state + // to managerResultChan. + managerCtx, managerCancel := context.WithCancel(context.Background()) + defer managerCancel() + managerResultChan := make(chan error) go func() { - // spam update on component trying to cause a deadlock - comp := comp - i := 0 - for { - if updatedCtx.Err() != nil { - return - } - updatedComp := comp - updatedComp.Units = make([]component.Unit, 1) - updatedComp.Units[0] = component.Unit{ - ID: "fake-input", - Type: client.UnitTypeInput, - LogLevel: client.UnitLogLevelError, // test log will get spammed with the constant updates (error to prevent spam) - Config: component.MustExpectedConfig(map[string]interface{}{ - "type": "fake", - "state": int(client.UnitStateHealthy), - "message": fmt.Sprintf("Fake Healthy %d", i), - }), - } - i += 1 - comp = updatedComp - m.Update(component.Model{Components: []component.Component{updatedComp}}) - err := <-m.errCh - if err != nil { - updatedErr <- err - return - } - updatedCh <- time.Now() - } + managerResultChan <- m.Run(managerCtx) }() - deadlockErr := make(chan error) + // Wait for the manager to become active + timedWaitForReady(t, m, 1*time.Second) + + // Start a goroutine to spam the manager update trying to cause + // a deadlock. When the test context finishes, the update loop + // closes updateResultChan to signal that it is done. + updateResultChan := make(chan error) + updateLoopCtx, updateLoopCancel := context.WithTimeout(context.Background(), testDuration) + defer updateLoopCancel() go func() { - t := time.NewTimer(15 * time.Second) - defer t.Stop() - for { - select { - case <-updatedCtx.Done(): - return - case <-updatedCh: - // update did occur - t.Reset(15 * time.Second) - case <-t.C: - // timeout hit waiting for another update to work - deadlockErr <- errors.New("hit deadlock") + defer close(updateResultChan) + for i := 0; updateLoopCtx.Err() == nil; i++ { + comp := noDeadlockTestComponent(t, i) + m.Update(component.Model{Components: []component.Component{comp}}) + err := <-m.errCh + updateResultChan <- err + if err != nil { + // If the update gave an error, end the test return } } }() - defer drainErrChan(errCh) - defer drainErrChan(updatedErr) - defer drainErrChan(deadlockErr) - - // wait 2 minutes for a deadlock to occur - endTimer := time.NewTimer(2 * time.Minute) - defer endTimer.Stop() + // The component state is being changed constantly. If updateTimeout + // triggers without any updates, report it as a deadlock. + updateTimeout := time.NewTicker(maxUpdateInterval) + defer updateTimeout.Stop() LOOP: for { select { - case <-endTimer.C: - // no deadlock after timeout (all good stop the component) - updatedCancel() - m.Update(component.Model{Components: []component.Component{}}) - <-m.errCh // Don't care about the result of Update, just that it runs - break LOOP - case err := <-errCh: - require.NoError(t, err) - case err := <-updatedErr: - require.NoError(t, err) - break LOOP - case err := <-deadlockErr: - require.NoError(t, err) - break LOOP + case err, ok := <-updateResultChan: + if ok { + // update did occur + require.NoError(t, err) + updateTimeout.Reset(15 * time.Second) + } else { + // Update goroutine is terminating, test is over + break LOOP + } + case <-managerResultChan: + require.Fail(t, "Runtime manager terminated before test was over") + case <-updateTimeout.C: + require.Fail(t, "Timed out waiting for Manager.Update result") } } - - updatedCancel() - cancel() - - err = <-errCh + // Finished without a deadlock. Stop the component and shut down the manager. + m.Update(component.Model{Components: []component.Component{}}) + err = <-m.errCh require.NoError(t, err) + + managerCancel() + err = <-managerResultChan + require.Equal(t, err, context.Canceled) } func (suite *FakeInputSuite) TestManager_Configure() { diff --git a/pkg/core/process/process.go b/pkg/core/process/process.go index 69924ed6df4..a9c7aa26782 100644 --- a/pkg/core/process/process.go +++ b/pkg/core/process/process.go @@ -119,7 +119,9 @@ func (i *Info) StopWait() error { return err } -// Wait returns a channel that will send process state once it exits. +// Wait returns a channel that will send process state once it exits. Each +// call to Wait() creates a goroutine. Failure to read from the returned +// channel will leak this goroutine. func (i *Info) Wait() <-chan *os.ProcessState { ch := make(chan *os.ProcessState) diff --git a/pkg/packer/packer.go b/pkg/packer/packer.go index 6bec521fe1c..2b220290293 100644 --- a/pkg/packer/packer.go +++ b/pkg/packer/packer.go @@ -10,7 +10,7 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" + "os" "path/filepath" "strings" @@ -33,7 +33,7 @@ func Pack(patterns ...string) (string, []string, error) { return "", []string{}, errors.New(err, fmt.Sprintf("error while reading pattern %s", p)) } for _, f := range files { - b, err := ioutil.ReadFile(f) + b, err := os.ReadFile(f) if err != nil { return "", []string{}, errors.New(err, fmt.Sprintf("cannot read file %s", f)) } diff --git a/pkg/packer/packer_test.go b/pkg/packer/packer_test.go index 253aa8d5e7d..e85d124736c 100644 --- a/pkg/packer/packer_test.go +++ b/pkg/packer/packer_test.go @@ -6,7 +6,6 @@ package packer import ( "crypto/rand" - "io/ioutil" "os" "path/filepath" "reflect" @@ -25,13 +24,13 @@ func TestPacker(t *testing.T) { withFiles := func(test tt, fn func(pattern []string, t *testing.T)) func(t *testing.T) { return func(t *testing.T) { - d, err := ioutil.TempDir("", "packer") + d, err := os.MkdirTemp("", "packer") require.NoError(t, err) defer os.RemoveAll(d) for f, v := range test.content { path := filepath.Join(d, f) - err := ioutil.WriteFile(path, []byte(v), 0666) + err := os.WriteFile(path, []byte(v), 0666) require.NoError(t, err) } diff --git a/pkg/testing/ess/statful_provisioner.go b/pkg/testing/ess/statful_provisioner.go index 32dc70707ef..a9de4b3bbb8 100644 --- a/pkg/testing/ess/statful_provisioner.go +++ b/pkg/testing/ess/statful_provisioner.go @@ -8,6 +8,7 @@ import ( "context" "errors" "fmt" + "os" "strings" "time" @@ -71,14 +72,21 @@ func (p *statefulProvisioner) Create(ctx context.Context, request runner.StackRe // allow up to 2 minutes for request createCtx, createCancel := context.WithTimeout(ctx, 2*time.Minute) defer createCancel() - resp, err := p.createDeployment(createCtx, request, - map[string]string{ - "division": "engineering", - "org": "ingest", - "team": "elastic-agent", - "project": "elastic-agent", - "integration-tests": "true", - }) + deploymentTags := map[string]string{ + "division": "engineering", + "org": "ingest", + "team": "elastic-agent", + "project": "elastic-agent", + "integration-tests": "true", + } + // If the CI env var is set, this mean we are running inside the CI pipeline and some expected env vars are exposed + if _, e := os.LookupEnv("CI"); e { + deploymentTags["buildkite_id"] = os.Getenv("BUILDKITE_BUILD_NUMBER") + deploymentTags["creator"] = os.Getenv("BUILDKITE_BUILD_CREATOR") + deploymentTags["buildkite_url"] = os.Getenv("BUILDKITE_BUILD_URL") + deploymentTags["ci"] = "true" + } + resp, err := p.createDeployment(createCtx, request, deploymentTags) if err != nil { return runner.Stack{}, err } diff --git a/pkg/testing/fixture.go b/pkg/testing/fixture.go index 43e290a6a07..7a1b45ee49a 100644 --- a/pkg/testing/fixture.go +++ b/pkg/testing/fixture.go @@ -9,7 +9,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -313,9 +312,10 @@ func (f *Fixture) RunBeat(ctx context.Context) error { return fmt.Errorf("failed to spawn %s: %w", f.binaryName, err) } + procWaitCh := proc.Wait() killProc := func() { _ = proc.Kill() - <-proc.Wait() + <-procWaitCh } var doneChan <-chan time.Time @@ -329,7 +329,7 @@ func (f *Fixture) RunBeat(ctx context.Context) error { case <-ctx.Done(): killProc() return ctx.Err() - case ps := <-proc.Wait(): + case ps := <-procWaitCh: if stopping { return nil } @@ -385,9 +385,10 @@ func RunProcess(t *testing.T, return fmt.Errorf("failed to spawn %q: %w", processPath, err) } + procWaitCh := proc.Wait() killProc := func() { _ = proc.Kill() - <-proc.Wait() + <-procWaitCh } var doneChan <-chan time.Time @@ -401,7 +402,7 @@ func RunProcess(t *testing.T, case <-ctx.Done(): killProc() return ctx.Err() - case ps := <-proc.Wait(): + case ps := <-procWaitCh: if stopping { return nil } @@ -444,7 +445,7 @@ func RunProcess(t *testing.T, // when `Run` is called. // // if shouldWatchState is set to false, communicating state does not happen. -func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, states ...State) error { +func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, enableTestingMode bool, states ...State) error { if _, deadlineSet := ctx.Deadline(); !deadlineSet { f.t.Fatal("Context passed to Fixture.Run() has no deadline set.") } @@ -483,13 +484,6 @@ func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, stat return fmt.Errorf("failed to get control protcol address: %w", err) } - if shouldWatchState { - agentClient = client.New(client.WithAddress(cAddr)) - f.setClient(agentClient) - defer f.setClient(nil) - stateCh, stateErrCh = watchState(ctx, f.t, agentClient, f.connectTimout) - } - var logProxy Logger if f.logOutput { logProxy = f.t @@ -497,7 +491,10 @@ func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, stat stdOut := newLogWatcher(logProxy) stdErr := newLogWatcher(logProxy) - args := []string{"run", "-e", "--disable-encrypted-store", "--testing-mode"} + args := []string{"run", "-e", "--disable-encrypted-store"} + if enableTestingMode { + args = append(args, "--testing-mode") + } args = append(args, f.additionalArgs...) @@ -511,9 +508,11 @@ func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, stat return fmt.Errorf("failed to spawn %s: %w", f.binaryName, err) } - killProc := func() { - _ = proc.Kill() - <-proc.Wait() + if shouldWatchState { + agentClient = client.New(client.WithAddress(cAddr)) + f.setClient(agentClient) + defer f.setClient(nil) + stateCh, stateErrCh = watchState(ctx, f.t, agentClient, f.connectTimout) } var doneChan <-chan time.Time @@ -521,13 +520,19 @@ func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, stat doneChan = time.After(f.runLength) } + procWaitCh := proc.Wait() + killProc := func() { + _ = proc.Kill() + <-procWaitCh + } + stopping := false for { select { case <-ctx.Done(): killProc() return ctx.Err() - case ps := <-proc.Wait(): + case ps := <-procWaitCh: if stopping { return nil } @@ -599,7 +604,7 @@ func (f *Fixture) RunWithClient(ctx context.Context, shouldWatchState bool, stat // The `elastic-agent.yml` generated by `Fixture.Configure` is ignored // when `Run` is called. func (f *Fixture) Run(ctx context.Context, states ...State) error { - return f.RunWithClient(ctx, true, states...) + return f.RunWithClient(ctx, true, true, states...) } // Exec provides a way of performing subcommand on the prepared Elastic Agent binary. @@ -839,7 +844,7 @@ func (f *Fixture) prepareComponents(workDir string, components ...UsableComponen if err != nil { return err } - contents, err := ioutil.ReadDir(componentsDir) + contents, err := os.ReadDir(componentsDir) if err != nil { return fmt.Errorf("failed to read contents of components directory %s: %w", componentsDir, err) } @@ -979,7 +984,7 @@ func getCacheDir(caller string, name string) (string, error) { // FindComponentsDir identifies the directory that holds the components. func FindComponentsDir(dir string) (string, error) { dataDir := filepath.Join(dir, "data") - agentVersions, err := ioutil.ReadDir(dataDir) + agentVersions, err := os.ReadDir(dataDir) if err != nil { return "", fmt.Errorf("failed to read contents of the data directory %s: %w", dataDir, err) } diff --git a/pkg/testing/fixture_install.go b/pkg/testing/fixture_install.go index 85ac868817b..a9872d66035 100644 --- a/pkg/testing/fixture_install.go +++ b/pkg/testing/fixture_install.go @@ -57,13 +57,25 @@ type InstallOpts struct { Insecure bool // --insecure NonInteractive bool // --non-interactive ProxyURL string // --proxy-url - Unprivileged bool // --unprivileged DelayEnroll bool // --delay-enroll + // Unprivileged by default installs the Elastic Agent as `--unprivileged` unless + // the platform being tested doesn't currently support it, or it's explicitly set + // to false. + Unprivileged *bool // --unprivileged + EnrollOpts } -func (i InstallOpts) toCmdArgs() []string { +func (i InstallOpts) IsUnprivileged(operatingSystem string) bool { + if i.Unprivileged == nil { + // not explicitly set, default to true on Linux only (until other platforms support it) + return operatingSystem == "linux" + } + return *i.Unprivileged +} + +func (i InstallOpts) toCmdArgs(operatingSystem string) ([]string, error) { var args []string if i.BasePath != "" { args = append(args, "--base-path", i.BasePath) @@ -80,16 +92,26 @@ func (i InstallOpts) toCmdArgs() []string { if i.ProxyURL != "" { args = append(args, "--proxy-url="+i.ProxyURL) } - if i.Unprivileged { - args = append(args, "--unprivileged") - } if i.DelayEnroll { args = append(args, "--delay-enroll") } + unprivileged := i.IsUnprivileged(operatingSystem) + if unprivileged { + if operatingSystem != "linux" { + return nil, fmt.Errorf("--unprivileged cannot be set to true unless testing is being done on Linux") + } + args = append(args, "--unprivileged") + } + args = append(args, i.EnrollOpts.toCmdArgs()...) - return args + return args, nil +} + +// NewBool returns a boolean pointer. +func NewBool(value bool) *bool { + return &value } // Install installs the prepared Elastic Agent binary and registers a t.Cleanup @@ -102,9 +124,15 @@ func (i InstallOpts) toCmdArgs() []string { func (f *Fixture) Install(ctx context.Context, installOpts *InstallOpts, opts ...process.CmdOption) ([]byte, error) { f.t.Logf("[test %s] Inside fixture install function", f.t.Name()) installArgs := []string{"install"} - if installOpts != nil { - installArgs = append(installArgs, installOpts.toCmdArgs()...) + if installOpts == nil { + // default options when not provided + installOpts = &InstallOpts{} + } + installOptsArgs, err := installOpts.toCmdArgs(f.operatingSystem) + if err != nil { + return nil, err } + installArgs = append(installArgs, installOptsArgs...) out, err := f.Exec(ctx, installArgs, opts...) if err != nil { return out, fmt.Errorf("error running agent install command: %w", err) @@ -125,7 +153,7 @@ func (f *Fixture) Install(ctx context.Context, installOpts *InstallOpts, opts .. // Windows uses a fixed named pipe, that is always the same. // It is the same even running in unprivileged mode. socketPath = paths.WindowsControlSocketInstalledPath - } else if installOpts.Unprivileged { + } else if installOpts.IsUnprivileged(f.operatingSystem) { // Unprivileged versions move the socket to inside the installed directory // of the Elastic Agent. socketPath = paths.ControlSocketFromPath(runtime.GOOS, f.workDir) diff --git a/pkg/testing/tools/tools.go b/pkg/testing/tools/tools.go index 09d2575982f..44d27d24401 100644 --- a/pkg/testing/tools/tools.go +++ b/pkg/testing/tools/tools.go @@ -139,12 +139,3 @@ func InstallAgentForPolicy(ctx context.Context, t *testing.T, return nil } - -// InstallStandaloneAgent force install the Elastic Agent through agentFixture. -func InstallStandaloneAgent(ctx context.Context, agentFixture *atesting.Fixture) ([]byte, error) { - installOpts := atesting.InstallOpts{ - NonInteractive: true, - Force: true, - } - return agentFixture.Install(ctx, &installOpts) -} diff --git a/specs/endpoint-security.spec.yml b/specs/endpoint-security.spec.yml index 1be7f37def1..4f3a2ff7e42 100644 --- a/specs/endpoint-security.spec.yml +++ b/specs/endpoint-security.spec.yml @@ -15,9 +15,9 @@ inputs: runtime: preventions: - condition: ${runtime.arch} == 'arm64' and ${runtime.family} == 'redhat' and ${runtime.major} == '7' - message: "No support for RHEL7 on arm64" + message: "Elastic Defend doesn't support RHEL7 on arm64" - condition: ${user.root} == false - message: "Elastic Agent must be running as root" + message: "Elastic Defend requires Elastic Agent be running as root" - condition: ${install.in_default} == false message: "Elastic Defend requires Elastic Agent be installed at the default installation path" service: &service @@ -56,6 +56,8 @@ inputs: proxied_actions: *proxied_actions runtime: preventions: + - condition: ${user.root} == false + message: "Elastic Defend requires Elastic Agent be running as root" - condition: ${install.in_default} == false message: "Elastic Defend requires Elastic Agent be installed at the default installation path" service: @@ -72,7 +74,7 @@ inputs: runtime: preventions: - condition: ${user.root} == false - message: "Elastic Agent must be running as Administrator or SYSTEM" + message: "Elastic Defend requires Elastic Agent be running as Administrator or SYSTEM" - condition: ${install.in_default} == false message: "Elastic Defend requires Elastic Agent be installed at the default installation path" service: diff --git a/testing/integration/apm_propagation_test.go b/testing/integration/apm_propagation_test.go index af778837899..83b76e7db34 100644 --- a/testing/integration/apm_propagation_test.go +++ b/testing/integration/apm_propagation_test.go @@ -13,7 +13,6 @@ import ( "fmt" "io" "net/http" - "runtime" "strings" "testing" "text/template" @@ -57,12 +56,6 @@ func TestAPMConfig(t *testing.T) { Group: Default, Stack: &define.Stack{}, }) - - if runtime.GOOS == "windows" { - // This test hangs indefinitely on Windows. Root cause is TBD. - t.Skip("Flaky test: https://github.com/elastic/ingest-dev/issues/2668") - } - f, err := define.NewFixture(t, define.Version()) require.NoError(t, err) diff --git a/testing/integration/endpoint_security_test.go b/testing/integration/endpoint_security_test.go index b5418dab5fa..275b4b31d84 100644 --- a/testing/integration/endpoint_security_test.go +++ b/testing/integration/endpoint_security_test.go @@ -14,6 +14,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "testing" "text/template" @@ -184,6 +185,7 @@ func testInstallAndCLIUninstallWithEndpointSecurity(t *testing.T, info *define.I installOpts := atesting.InstallOpts{ NonInteractive: true, Force: true, + Unprivileged: atesting.NewBool(false), } policy, err := tools.InstallAgentWithPolicy(ctx, t, @@ -242,6 +244,7 @@ func testInstallAndUnenrollWithEndpointSecurity(t *testing.T, info *define.Info, installOpts := atesting.InstallOpts{ NonInteractive: true, Force: true, + Unprivileged: atesting.NewBool(false), } ctx, cn := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) @@ -354,6 +357,7 @@ func testInstallWithEndpointSecurityAndRemoveEndpointIntegration(t *testing.T, i installOpts := atesting.InstallOpts{ NonInteractive: true, Force: true, + Unprivileged: atesting.NewBool(false), } ctx, cn := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) @@ -521,6 +525,7 @@ func TestEndpointSecurityNonDefaultBasePath(t *testing.T) { installOpts := atesting.InstallOpts{ NonInteractive: true, Force: true, + Unprivileged: atesting.NewBool(false), BasePath: filepath.Join(paths.DefaultBasePath, "not_default"), } policyResp, err := tools.InstallAgentWithPolicy(ctx, t, installOpts, fixture, info.KibanaClient, createPolicyReq) @@ -561,6 +566,86 @@ func TestEndpointSecurityNonDefaultBasePath(t *testing.T) { }, 2*time.Minute, 10*time.Second, "Agent never became DEGRADED with default install message") } +// Tests that install of Elastic Defend fails if Agent is installed unprivileged. +func TestEndpointSecurityUnprivileged(t *testing.T) { + info := define.Require(t, define.Requirements{ + Group: Fleet, + Stack: &define.Stack{}, + Local: false, // requires Agent installation + Sudo: true, // requires Agent installation + + // Only supports Linux at the moment. + OS: []define.OS{ + { + Type: define.Linux, + }, + }, + }) + + ctx, cn := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cn() + + // Get path to agent executable. + fixture, err := define.NewFixture(t, define.Version()) + require.NoError(t, err) + + t.Log("Enrolling the agent in Fleet") + policyUUID := uuid.New().String() + createPolicyReq := kibana.AgentPolicy{ + Name: "test-policy-" + policyUUID, + Namespace: "default", + Description: "Test policy " + policyUUID, + MonitoringEnabled: []kibana.MonitoringEnabledOption{ + kibana.MonitoringEnabledLogs, + kibana.MonitoringEnabledMetrics, + }, + } + installOpts := atesting.InstallOpts{ + NonInteractive: true, + Force: true, + Unprivileged: atesting.NewBool(true), // ensure always unprivileged + } + policyResp, err := tools.InstallAgentWithPolicy(ctx, t, installOpts, fixture, info.KibanaClient, createPolicyReq) + require.NoErrorf(t, err, "Policy Response was: %v", policyResp) + + t.Log("Installing Elastic Defend") + pkgPolicyResp, err := installElasticDefendPackage(t, info, policyResp.ID) + require.NoErrorf(t, err, "Policy Response was: %v", pkgPolicyResp) + + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + c := fixture.Client() + + errMsg := "Elastic Defend requires Elastic Agent be running as root" + if runtime.GOOS == define.Windows { + errMsg = "Elastic Defend requires Elastic Agent be running as Administrator or SYSTEM" + } + require.Eventually(t, func() bool { + err := c.Connect(ctx) + if err != nil { + t.Logf("connecting client to agent: %v", err) + return false + } + defer c.Disconnect() + state, err := c.State(ctx) + if err != nil { + t.Logf("error getting the agent state: %v", err) + return false + } + t.Logf("agent state: %+v", state) + if state.State != cproto.State_DEGRADED { + return false + } + for _, c := range state.Components { + if strings.Contains(c.Message, errMsg) { + return true + } + } + return false + }, 2*time.Minute, 10*time.Second, "Agent never became DEGRADED with root/Administrator install message") +} + func agentAndEndpointAreHealthy(t *testing.T, ctx context.Context, agentClient client.Client) bool { t.Helper() diff --git a/testing/integration/groups_test.go b/testing/integration/groups_test.go index edf22180809..d6311cc7eb6 100644 --- a/testing/integration/groups_test.go +++ b/testing/integration/groups_test.go @@ -15,9 +15,16 @@ const ( // Fleet group of tests. Used for testing Elastic Agent with Fleet. Fleet = "fleet" + // FleetPrivileged group of tests. Used for testing Elastic Agent with Fleet installed privileged. + FleetPrivileged = "fleet-privileged" + // FleetAirgapped group of tests. Used for testing Elastic Agent with Fleet and airgapped. FleetAirgapped = "fleet-airgapped" + // FleetAirgappedPrivileged group of tests. Used for testing Elastic Agent with Fleet installed + // privileged and airgapped. + FleetAirgappedPrivileged = "fleet-airgapped-privileged" + // FQDN group of tests. Used for testing Elastic Agent with FQDN enabled. FQDN = "fqdn" diff --git a/testing/integration/install_privileged_test.go b/testing/integration/install_privileged_test.go new file mode 100644 index 00000000000..9cc8db6b09e --- /dev/null +++ b/testing/integration/install_privileged_test.go @@ -0,0 +1,122 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build integration + +package integration + +import ( + "context" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + atesting "github.com/elastic/elastic-agent/pkg/testing" + "github.com/elastic/elastic-agent/pkg/testing/define" + "github.com/elastic/elastic-agent/pkg/testing/tools/testcontext" + + "github.com/stretchr/testify/require" +) + +func TestInstallPrivilegedWithoutBasePath(t *testing.T) { + define.Require(t, define.Requirements{ + Group: Default, + // We require sudo for this test to run + // `elastic-agent install`. + Sudo: true, + + // It's not safe to run this test locally as it + // installs Elastic Agent. + Local: false, + }) + + // Get path to Elastic Agent executable + fixture, err := define.NewFixture(t, define.Version()) + require.NoError(t, err) + + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + // Prepare the Elastic Agent so the binary is extracted and ready to use. + err = fixture.Prepare(ctx) + require.NoError(t, err) + + // Check that default base path is clean + var defaultBasePath string + switch runtime.GOOS { + case "darwin": + defaultBasePath = `/Library` + case "linux": + defaultBasePath = `/opt` + case "windows": + defaultBasePath = `C:\Program Files` + } + + topPath := filepath.Join(defaultBasePath, "Elastic", "Agent") + err = os.RemoveAll(topPath) + require.NoError(t, err, "failed to remove %q. The test requires this path not to exist.") + + // Run `elastic-agent install`. We use `--force` to prevent interactive + // execution. + opts := &atesting.InstallOpts{Force: true, Unprivileged: atesting.NewBool(false)} + out, err := fixture.Install(ctx, opts) + if err != nil { + t.Logf("install output: %s", out) + require.NoError(t, err) + } + + // Check that Agent was installed in default base path + checkInstallSuccess(t, topPath, opts.IsUnprivileged(runtime.GOOS)) + t.Run("check agent package version", testAgentPackageVersion(ctx, fixture, true)) +} + +func TestInstallPrivilegedWithBasePath(t *testing.T) { + define.Require(t, define.Requirements{ + Group: Default, + // We require sudo for this test to run + // `elastic-agent install`. + Sudo: true, + + // It's not safe to run this test locally as it + // installs Elastic Agent. + Local: false, + }) + + // Get path to Elastic Agent executable + fixture, err := define.NewFixture(t, define.Version()) + require.NoError(t, err) + + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + // Prepare the Elastic Agent so the binary is extracted and ready to use. + err = fixture.Prepare(ctx) + require.NoError(t, err) + + // Set up random temporary directory to serve as base path for Elastic Agent + // installation. + tmpDir := t.TempDir() + randomBasePath := filepath.Join(tmpDir, strings.ToLower(randStr(8))) + + // Run `elastic-agent install`. We use `--force` to prevent interactive + // execution. + opts := &atesting.InstallOpts{ + BasePath: randomBasePath, + Force: true, + Unprivileged: atesting.NewBool(false), + } + out, err := fixture.Install(ctx, opts) + if err != nil { + t.Logf("install output: %s", out) + require.NoError(t, err) + } + + // Check that Agent was installed in the custom base path + topPath := filepath.Join(randomBasePath, "Elastic", "Agent") + checkInstallSuccess(t, topPath, opts.IsUnprivileged(runtime.GOOS)) + t.Run("check agent package version", testAgentPackageVersion(ctx, fixture, true)) +} diff --git a/testing/integration/install_test.go b/testing/integration/install_test.go index 8e8407a9dd8..43afd1fc2bc 100644 --- a/testing/integration/install_test.go +++ b/testing/integration/install_test.go @@ -10,24 +10,26 @@ import ( "context" "math/rand" "os" + "os/exec" "path/filepath" "runtime" "strings" "testing" "time" + "github.com/stretchr/testify/require" + atesting "github.com/elastic/elastic-agent/pkg/testing" "github.com/elastic/elastic-agent/pkg/testing/define" "github.com/elastic/elastic-agent/pkg/testing/tools/testcontext" - - "github.com/stretchr/testify/require" ) func TestInstallWithoutBasePath(t *testing.T) { define.Require(t, define.Requirements{ Group: Default, // We require sudo for this test to run - // `elastic-agent install`. + // `elastic-agent install` (even though it will + // be installed as non-root). Sudo: true, // It's not safe to run this test locally as it @@ -63,22 +65,38 @@ func TestInstallWithoutBasePath(t *testing.T) { // Run `elastic-agent install`. We use `--force` to prevent interactive // execution. - out, err := fixture.Install(ctx, &atesting.InstallOpts{Force: true}) + opts := &atesting.InstallOpts{Force: true} + out, err := fixture.Install(ctx, opts) if err != nil { t.Logf("install output: %s", out) require.NoError(t, err) } // Check that Agent was installed in default base path - checkInstallSuccess(t, topPath) + checkInstallSuccess(t, topPath, opts.IsUnprivileged(runtime.GOOS)) t.Run("check agent package version", testAgentPackageVersion(ctx, fixture, true)) + // Make sure uninstall from within the topPath fails on Windows + if runtime.GOOS == "windows" { + cwd, err := os.Getwd() + require.NoErrorf(t, err, "GetWd failed: %s", err) + err = os.Chdir(topPath) + require.NoErrorf(t, err, "Chdir to topPath failed: %s", err) + t.Cleanup(func() { + _ = os.Chdir(cwd) + }) + out, err = fixture.Uninstall(ctx, &atesting.UninstallOpts{Force: true}) + require.Error(t, err, "uninstall should have failed") + require.Containsf(t, string(out), "uninstall must be run from outside the installed path", "expected error string not found in: %s err: %s", out, err) + } + } func TestInstallWithBasePath(t *testing.T) { define.Require(t, define.Requirements{ Group: Default, // We require sudo for this test to run - // `elastic-agent install`. + // `elastic-agent install` (even though it will + // be installed as non-root). Sudo: true, // It's not safe to run this test locally as it @@ -100,26 +118,56 @@ func TestInstallWithBasePath(t *testing.T) { // Set up random temporary directory to serve as base path for Elastic Agent // installation. tmpDir := t.TempDir() - randomBasePath := filepath.Join(tmpDir, strings.ToLower(randStr(8))) + basePath := filepath.Join(tmpDir, strings.ToLower(randStr(8))) // Run `elastic-agent install`. We use `--force` to prevent interactive // execution. - out, err := fixture.Install(ctx, &atesting.InstallOpts{ - BasePath: randomBasePath, + opts := &atesting.InstallOpts{ + BasePath: basePath, Force: true, - }) + } + if opts.IsUnprivileged(runtime.GOOS) { + switch runtime.GOOS { + case define.Linux: + // When installing with unprivileged using a base path the + // base needs to be accessible by the `elastic-agent` user that will be + // executing the process, but is not created yet. Using a base that exists + // and is known to be accessible by standard users, ensures this tests + // works correctly and will not hit a permission issue when spawning the + // elastic-agent service. + basePath = `/usr` + default: + t.Fatalf("only Linux supports unprivileged mode") + } + opts.BasePath = basePath + } + + out, err := fixture.Install(ctx, opts) if err != nil { t.Logf("install output: %s", out) require.NoError(t, err) } // Check that Agent was installed in the custom base path - topPath := filepath.Join(randomBasePath, "Elastic", "Agent") - checkInstallSuccess(t, topPath) + topPath := filepath.Join(basePath, "Elastic", "Agent") + checkInstallSuccess(t, topPath, opts.IsUnprivileged(runtime.GOOS)) t.Run("check agent package version", testAgentPackageVersion(ctx, fixture, true)) + // Make sure uninstall from within the topPath fails on Windows + if runtime.GOOS == "windows" { + cwd, err := os.Getwd() + require.NoErrorf(t, err, "GetWd failed: %s", err) + err = os.Chdir(topPath) + require.NoErrorf(t, err, "Chdir to topPath failed: %s", err) + t.Cleanup(func() { + _ = os.Chdir(cwd) + }) + out, err = fixture.Uninstall(ctx, &atesting.UninstallOpts{Force: true}) + require.Error(t, err, "uninstall should have failed") + require.Containsf(t, string(out), "uninstall must be run from outside the installed path", "expected error string not found in: %s err: %s", out, err) + } } -func checkInstallSuccess(t *testing.T, topPath string) { +func checkInstallSuccess(t *testing.T, topPath string, unprivileged bool) { t.Helper() _, err := os.Stat(topPath) require.NoError(t, err) @@ -135,6 +183,28 @@ func checkInstallSuccess(t *testing.T, topPath string) { require.NoError(t, err) _, err = os.Stat(installMarkerPath) require.NoError(t, err) + + if unprivileged { + // Specific checks depending on the platform. + checkPlatformUnprivileged(t, topPath) + + // Executing `elastic-agent status` as the `elastic-agent` user should work. + var output []byte + require.Eventuallyf(t, func() bool { + cmd := exec.Command("sudo", "-u", "elastic-agent", "elastic-agent", "status") + output, err = cmd.CombinedOutput() + return err == nil + }, 3*time.Minute, 1*time.Second, "status never successful: %s (output: %s)", err, output) + + // Executing `elastic-agent status` as the original user should fail, because that + // user is not in the 'elastic-agent' group. + originalUser := os.Getenv("SUDO_USER") + if originalUser != "" { + cmd := exec.Command("sudo", "-u", originalUser, "elastic-agent", "status") + output, err := cmd.CombinedOutput() + require.Error(t, err, "running sudo -u %s elastic-agent status should have failed: %s", originalUser, output) + } + } } func randStr(length int) string { diff --git a/testing/integration/install_unix_test.go b/testing/integration/install_unix_test.go new file mode 100644 index 00000000000..302c6a6b218 --- /dev/null +++ b/testing/integration/install_unix_test.go @@ -0,0 +1,49 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build integration && !windows + +package integration + +import ( + "os" + "path/filepath" + "syscall" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" + "github.com/elastic/elastic-agent/internal/pkg/agent/install" +) + +func checkPlatformUnprivileged(t *testing.T, topPath string) { + // Check that the elastic-agent user/group exist. + uid, err := install.FindUID("elastic-agent") + require.NoError(t, err) + gid, err := install.FindGID("elastic-agent") + require.NoError(t, err) + + // Path should now exist as well as be owned by the correct user/group. + info, err := os.Stat(topPath) + require.NoError(t, err) + fs, ok := info.Sys().(*syscall.Stat_t) + require.True(t, ok) + require.Equalf(t, fs.Uid, uint32(uid), "%s not owned by elastic-agent user", topPath) + require.Equalf(t, fs.Gid, uint32(gid), "%s not owned by elastic-agent group", topPath) + + // Check that the socket is created with the correct permissions. + socketPath := filepath.Join(topPath, paths.ControlSocketName) + require.Eventuallyf(t, func() bool { + _, err = os.Stat(socketPath) + return err == nil + }, 3*time.Minute, 1*time.Second, "%s socket never created: %s", socketPath, err) + info, err = os.Stat(socketPath) + require.NoError(t, err) + fs, ok = info.Sys().(*syscall.Stat_t) + require.True(t, ok) + require.Equalf(t, fs.Uid, uint32(uid), "%s not owned by elastic-agent user", socketPath) + require.Equalf(t, fs.Gid, uint32(gid), "%s not owned by elastic-agent group", socketPath) +} diff --git a/testing/integration/install_unprivileged_test.go b/testing/integration/install_unprivileged_test.go deleted file mode 100644 index 87dd1b0e339..00000000000 --- a/testing/integration/install_unprivileged_test.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License; -// you may not use this file except in compliance with the Elastic License. - -//go:build integration && !windows - -package integration - -import ( - "context" - "os" - "os/exec" - "path/filepath" - "runtime" - "syscall" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/elastic/elastic-agent/internal/pkg/agent/application/paths" - "github.com/elastic/elastic-agent/internal/pkg/agent/install" - atesting "github.com/elastic/elastic-agent/pkg/testing" - "github.com/elastic/elastic-agent/pkg/testing/define" - "github.com/elastic/elastic-agent/pkg/testing/tools/testcontext" -) - -func TestInstallUnprivilegedWithoutBasePath(t *testing.T) { - define.Require(t, define.Requirements{ - Group: Default, - // We require sudo for this test to run - // `elastic-agent install` (even though it will - // be installed as non-root). - Sudo: true, - - // It's not safe to run this test locally as it - // installs Elastic Agent. - Local: false, - - // Only supports Linux at the moment. - OS: []define.OS{ - { - Type: define.Linux, - }, - }, - }) - - // Get path to Elastic Agent executable - fixture, err := define.NewFixture(t, define.Version()) - require.NoError(t, err) - - ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) - defer cancel() - - // Prepare the Elastic Agent so the binary is extracted and ready to use. - err = fixture.Prepare(ctx) - require.NoError(t, err) - - // Check that default base path is clean - var defaultBasePath string - switch runtime.GOOS { - case "darwin": - defaultBasePath = `/Library` - case "linux": - defaultBasePath = `/opt` - case "windows": - defaultBasePath = `C:\Program Files` - } - - topPath := filepath.Join(defaultBasePath, "Elastic", "Agent") - err = os.RemoveAll(topPath) - require.NoError(t, err, "failed to remove %q. The test requires this path not to exist.") - - // Run `elastic-agent install`. We use `--force` to prevent interactive - // execution. - out, err := fixture.Install(ctx, &atesting.InstallOpts{Force: true, Unprivileged: true}) - if err != nil { - t.Logf("install output: %s", out) - require.NoError(t, err) - } - - checkInstallUnprivilegedSuccess(t, topPath) -} - -func TestInstallUnprivilegedWithBasePath(t *testing.T) { - define.Require(t, define.Requirements{ - Group: Default, - // We require sudo for this test to run - // `elastic-agent install` (even though it will - // be installed as non-root). - Sudo: true, - - // It's not safe to run this test locally as it - // installs Elastic Agent. - Local: false, - - // Only supports Linux at the moment. - OS: []define.OS{ - { - Type: define.Linux, - }, - }, - }) - - // Get path to Elastic Agent executable - fixture, err := define.NewFixture(t, define.Version()) - require.NoError(t, err) - - ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) - defer cancel() - - // Prepare the Elastic Agent so the binary is extracted and ready to use. - err = fixture.Prepare(ctx) - require.NoError(t, err) - - // Other test `TestInstallWithBasePath` uses a random directory for the base - // path and that works because its running root. When using a base path the - // base needs to be accessible by the `elastic-agent` user that will be - // executing the process, but is not created yet. Using a base that exists - // and is known to be accessible by standard users, ensures this tests - // works correctly and will not hit a permission issue when spawning the - // elastic-agent service. - var basePath string - switch runtime.GOOS { - case define.Linux: - // default is `/opt` - basePath = `/usr` - default: - t.Fatalf("only Linux is supported by this test; should have been skipped") - } - - // Run `elastic-agent install`. We use `--force` to prevent interactive - // execution. - out, err := fixture.Install(ctx, &atesting.InstallOpts{ - BasePath: basePath, - Force: true, - Unprivileged: true, - }) - if err != nil { - t.Logf("install output: %s", out) - require.NoError(t, err) - } - - // Check that Agent was installed in the custom base path - topPath := filepath.Join(basePath, "Elastic", "Agent") - checkInstallUnprivilegedSuccess(t, topPath) -} - -func checkInstallUnprivilegedSuccess(t *testing.T, topPath string) { - t.Helper() - - // Check that the elastic-agent user/group exist. - uid, err := install.FindUID("elastic-agent") - require.NoError(t, err) - gid, err := install.FindGID("elastic-agent") - require.NoError(t, err) - - // Path should now exist as well as be owned by the correct user/group. - info, err := os.Stat(topPath) - require.NoError(t, err) - fs, ok := info.Sys().(*syscall.Stat_t) - require.True(t, ok) - require.Equalf(t, fs.Uid, uint32(uid), "%s not owned by elastic-agent user", topPath) - require.Equalf(t, fs.Gid, uint32(gid), "%s not owned by elastic-agent group", topPath) - - // Check that a few expected installed files are present - installedBinPath := filepath.Join(topPath, exeOnWindows("elastic-agent")) - installedDataPath := filepath.Join(topPath, "data") - installMarkerPath := filepath.Join(topPath, ".installed") - _, err = os.Stat(installedBinPath) - require.NoError(t, err) - _, err = os.Stat(installedDataPath) - require.NoError(t, err) - _, err = os.Stat(installMarkerPath) - require.NoError(t, err) - - // Check that the socket is created with the correct permissions. - socketPath := filepath.Join(topPath, paths.ControlSocketName) - require.Eventuallyf(t, func() bool { - _, err = os.Stat(socketPath) - return err == nil - }, 3*time.Minute, 1*time.Second, "%s socket never created: %s", socketPath, err) - info, err = os.Stat(socketPath) - require.NoError(t, err) - fs, ok = info.Sys().(*syscall.Stat_t) - require.True(t, ok) - require.Equalf(t, fs.Uid, uint32(uid), "%s not owned by elastic-agent user", socketPath) - require.Equalf(t, fs.Gid, uint32(gid), "%s not owned by elastic-agent group", socketPath) - - // Executing `elastic-agent status` as the `elastic-agent` user should work. - var output []byte - require.Eventuallyf(t, func() bool { - cmd := exec.Command("sudo", "-u", "elastic-agent", "elastic-agent", "status") - output, err = cmd.CombinedOutput() - return err == nil - }, 3*time.Minute, 1*time.Second, "status never successful: %s (output: %s)", err, output) - - // Executing `elastic-agent status` as the original user should fail, because that - // user is not in the 'elastic-agent' group. - originalUser := os.Getenv("SUDO_USER") - if originalUser != "" { - cmd := exec.Command("sudo", "-u", originalUser, "elastic-agent", "status") - output, err := cmd.CombinedOutput() - require.Error(t, err, "running sudo -u %s elastic-agent status should have failed: %s", originalUser, output) - } -} diff --git a/testing/integration/install_windows_test.go b/testing/integration/install_windows_test.go new file mode 100644 index 00000000000..9d297af43a0 --- /dev/null +++ b/testing/integration/install_windows_test.go @@ -0,0 +1,15 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build integration && windows + +package integration + +import ( + "testing" +) + +func checkPlatformUnprivileged(t *testing.T, topPath string) { + // TODO (blakerouse): validate once Windows is supported +} diff --git a/testing/integration/logs_ingestion_test.go b/testing/integration/logs_ingestion_test.go index e8a86df4a0b..55756c1543b 100644 --- a/testing/integration/logs_ingestion_test.go +++ b/testing/integration/logs_ingestion_test.go @@ -95,7 +95,7 @@ func TestLogIngestionFleetManaged(t *testing.T) { }) t.Run("Normal logs with flattened data_stream are shipped", func(t *testing.T) { - testFlattenedDatastreamFleetPolicy(t, ctx, info, agentFixture, policy) + testFlattenedDatastreamFleetPolicy(t, ctx, info, policy) }) } @@ -250,7 +250,6 @@ func testFlattenedDatastreamFleetPolicy( t *testing.T, ctx context.Context, info *define.Info, - agentFixture *atesting.Fixture, policy kibana.PolicyResponse, ) { dsType := "logs" @@ -258,14 +257,18 @@ func testFlattenedDatastreamFleetPolicy( dsDataset := cleanString(fmt.Sprintf("%s-dataset", t.Name())) numEvents := 60 - tempDir := t.TempDir() - logFilePath := filepath.Join(tempDir, "log.log") - generateLogFile(t, logFilePath, 2*time.Millisecond, numEvents) - - agentFixture, err := define.NewFixture(t, define.Version()) + // tempDir is not deleted to help with debugging issues + // useful to check permissions on contents + tempDir, err := os.MkdirTemp("", "fleet-ingest-*") if err != nil { - t.Fatalf("could not create new fixture: %s", err) + t.Fatalf("failed to create temp directory: %s", err) } + err = os.Chmod(tempDir, 0o755) + if err != nil { + t.Fatalf("failed to chmod temp directory %s: %s", tempDir, err) + } + logFilePath := filepath.Join(tempDir, "log.log") + generateLogFile(t, logFilePath, 2*time.Millisecond, numEvents) // 1. Prepare a request to add an integration to the policy tmpl, err := template.New(t.Name() + "custom-log-policy").Parse(policyJSON) @@ -364,7 +367,11 @@ func generateLogFile(t *testing.T, fullPath string, tick time.Duration, events i t.Helper() f, err := os.Create(fullPath) if err != nil { - t.Fatalf("could not create file '%s: %s", fullPath, err) + t.Fatalf("could not create file '%s': %s", fullPath, err) + } + err = os.Chmod(fullPath, 0o644) + if err != nil { + t.Fatalf("failed to chmod file '%s': %s", fullPath, err) } go func() { diff --git a/testing/integration/otel_test.go b/testing/integration/otel_test.go index c3b22ef3723..6aa06c9031e 100644 --- a/testing/integration/otel_test.go +++ b/testing/integration/otel_test.go @@ -124,7 +124,7 @@ func TestOtelFileProcessing(t *testing.T) { fixtureWg.Add(1) go func() { defer fixtureWg.Done() - err = fixture.RunWithClient(ctx, false) + err = fixture.RunWithClient(ctx, false, false) }() var content []byte @@ -132,6 +132,23 @@ func TestOtelFileProcessing(t *testing.T) { `"stringValue":"syslog"`, // syslog is being processed `"stringValue":"system.log"`, // system.log is being processed }) + + // check `elastic-agent status` returns successfully + require.Eventuallyf(t, func() bool { + // This will return errors until it connects to the agent, + // they're mostly noise because until the agent starts running + // we will get connection errors. If the test fails + // the agent logs will be present in the error message + // which should help to explain why the agent was not + // healthy. + err := fixture.IsHealthy(ctx) + return err == nil + }, + 2*time.Minute, time.Second, + "Elastic-Agent did not report healthy. Agent status error: \"%v\"", + err, + ) + require.Eventually(t, func() bool { // verify file exists @@ -240,7 +257,7 @@ func TestOtelAPMIngestion(t *testing.T) { var fixtureWg sync.WaitGroup fixtureWg.Add(1) go func() { - fixture.RunWithClient(ctx, false) + fixture.RunWithClient(ctx, false, false) fixtureWg.Done() }() diff --git a/testing/integration/upgrade_fleet_test.go b/testing/integration/upgrade_fleet_test.go index 4103093dc9f..8452605adfc 100644 --- a/testing/integration/upgrade_fleet_test.go +++ b/testing/integration/upgrade_fleet_test.go @@ -35,17 +35,35 @@ import ( "github.com/elastic/elastic-agent/testing/upgradetest" ) -// TestFleetManagedUpgrade tests that the build under test can retrieve an action from -// Fleet and perform the upgrade. It does not need to test all the combinations of -// versions as the standalone tests already perform those tests and would be redundant. -func TestFleetManagedUpgrade(t *testing.T) { +// TestFleetManagedUpgradeUnprivileged tests that the build under test can retrieve an action from +// Fleet and perform the upgrade as an unprivileged Elastic Agent. It does not need to test +// all the combinations of versions as the standalone tests already perform those tests and +// would be redundant. +func TestFleetManagedUpgradeUnprivileged(t *testing.T) { info := define.Require(t, define.Requirements{ Group: Fleet, Stack: &define.Stack{}, Local: false, // requires Agent installation Sudo: true, // requires Agent installation }) + testFleetManagedUpgrade(t, info, true) +} +// TestFleetManagedUpgradePrivileged tests that the build under test can retrieve an action from +// Fleet and perform the upgrade as a privileged Elastic Agent. It does not need to test all +// the combinations of versions as the standalone tests already perform those tests and +// would be redundant. +func TestFleetManagedUpgradePrivileged(t *testing.T) { + info := define.Require(t, define.Requirements{ + Group: FleetPrivileged, + Stack: &define.Stack{}, + Local: false, // requires Agent installation + Sudo: true, // requires Agent installation + }) + testFleetManagedUpgrade(t, info, false) +} + +func testFleetManagedUpgrade(t *testing.T, info *define.Info, unprivileged bool) { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() @@ -61,13 +79,9 @@ func TestFleetManagedUpgrade(t *testing.T) { // Upgrade to a different build but of the same version (always a snapshot). // In the case there is not a different build then the test is skipped. // Fleet doesn't allow a downgrade to occur, so we cannot go to a lower version. - sameVersion := define.Version() - if !strings.HasSuffix(sameVersion, "-SNAPSHOT") { - sameVersion += "-SNAPSHOT" - } endFixture, err := atesting.NewFixture( t, - sameVersion, + upgradetest.EnsureSnapshot(define.Version()), atesting.WithFetcher(atesting.ArtifactFetcher()), ) require.NoError(t, err) @@ -86,10 +100,10 @@ func TestFleetManagedUpgrade(t *testing.T) { t.Logf("Testing Elastic Agent upgrade from %s to %s with Fleet...", define.Version(), endVersionInfo.Binary.String()) - testUpgradeFleetManagedElasticAgent(ctx, t, info, startFixture, endFixture, defaultPolicy()) + testUpgradeFleetManagedElasticAgent(ctx, t, info, startFixture, endFixture, defaultPolicy(), unprivileged) } -func TestFleetAirGappedUpgrade(t *testing.T) { +func TestFleetAirGappedUpgradeUnprivileged(t *testing.T) { stack := define.Require(t, define.Requirements{ Group: FleetAirgapped, Stack: &define.Stack{}, @@ -98,7 +112,22 @@ func TestFleetAirGappedUpgrade(t *testing.T) { Local: false, // Needed as the test requires Agent installation Sudo: true, // Needed as the test uses iptables and installs the Agent }) + testFleetAirGappedUpgrade(t, stack, true) +} +func TestFleetAirGappedUpgradePrivileged(t *testing.T) { + stack := define.Require(t, define.Requirements{ + Group: FleetAirgappedPrivileged, + Stack: &define.Stack{}, + // The test uses iptables to simulate the air-gaped environment. + OS: []define.OS{{Type: define.Linux}}, + Local: false, // Needed as the test requires Agent installation + Sudo: true, // Needed as the test uses iptables and installs the Agent + }) + testFleetAirGappedUpgrade(t, stack, false) +} + +func testFleetAirGappedUpgrade(t *testing.T, stack *define.Info, unprivileged bool) { ctx, _ := testcontext.WithDeadline( t, context.Background(), time.Now().Add(10*time.Minute)) @@ -163,7 +192,7 @@ func TestFleetAirGappedUpgrade(t *testing.T) { policy := defaultPolicy() policy.DownloadSourceID = src.Item.ID - testUpgradeFleetManagedElasticAgent(ctx, t, stack, fixture, upgradeTo, policy) + testUpgradeFleetManagedElasticAgent(ctx, t, stack, fixture, upgradeTo, policy, unprivileged) } func testUpgradeFleetManagedElasticAgent( @@ -172,7 +201,8 @@ func testUpgradeFleetManagedElasticAgent( info *define.Info, startFixture *atesting.Fixture, endFixture *atesting.Fixture, - policy kibana.AgentPolicy) { + policy kibana.AgentPolicy, + unprivileged bool) { kibClient := info.KibanaClient startVersionInfo, err := startFixture.ExecVersion(ctx) @@ -181,6 +211,20 @@ func testUpgradeFleetManagedElasticAgent( require.NoError(t, err) endVersionInfo, err := endFixture.ExecVersion(ctx) require.NoError(t, err) + endParsedVersion, err := version.ParseVersion(endVersionInfo.Binary.String()) + require.NoError(t, err) + + if unprivileged { + if startParsedVersion.Less(*upgradetest.Version_8_13_0) { + t.Skipf("Starting version %s is less than 8.13 and doesn't support --unprivileged", startParsedVersion.String()) + } + if endParsedVersion.Less(*upgradetest.Version_8_13_0) { + t.Skipf("Ending version %s is less than 8.13 and doesn't support --unprivileged", endParsedVersion.String()) + } + if runtime.GOOS != define.Linux { + t.Skip("Unprivileged mode is currently only supported on Linux") + } + } if startVersionInfo.Binary.Commit == endVersionInfo.Binary.Commit { t.Skipf("target version has the same commit hash %q", endVersionInfo.Binary.Commit) @@ -203,7 +247,7 @@ func testUpgradeFleetManagedElasticAgent( fleetServerURL, err := fleettools.DefaultURL(ctx, kibClient) require.NoError(t, err, "failed getting Fleet Server URL") - t.Log("Installing Elastic Agent...") + t.Logf("Installing Elastic Agent (unprivileged: %t)...", unprivileged) var nonInteractiveFlag bool if upgradetest.Version_8_2_0.Less(*startParsedVersion) { nonInteractiveFlag = true @@ -215,6 +259,7 @@ func testUpgradeFleetManagedElasticAgent( URL: fleetServerURL, EnrollmentToken: enrollmentToken.APIKey, }, + Unprivileged: atesting.NewBool(unprivileged), } output, err := startFixture.Install(ctx, &installOpts) require.NoError(t, err, "failed to install start agent [output: %s]", string(output)) diff --git a/testing/integration/upgrade_gpg_test.go b/testing/integration/upgrade_gpg_test.go index d1d9b6f3af1..ddb821cf719 100644 --- a/testing/integration/upgrade_gpg_test.go +++ b/testing/integration/upgrade_gpg_test.go @@ -30,10 +30,10 @@ func TestStandaloneUpgradeWithGPGFallback(t *testing.T) { }) minVersion := upgradetest.Version_8_10_0_SNAPSHOT - fromVersion, err := version.ParseVersion(define.Version()) + currentVersion, err := version.ParseVersion(define.Version()) require.NoError(t, err) - if fromVersion.Less(*minVersion) { + if currentVersion.Less(*minVersion) { t.Skipf("Version %s is lower than min version %s", define.Version(), minVersion) } @@ -44,18 +44,26 @@ func TestStandaloneUpgradeWithGPGFallback(t *testing.T) { // logic that is in the build. startFixture, err := define.NewFixture(t, define.Version()) require.NoError(t, err) - - // Upgrade to an old build. - upgradeToVersion, err := upgradetest.PreviousMinor(ctx, define.Version()) + startVersionInfo, err := startFixture.ExecVersion(ctx) require.NoError(t, err) + + // Upgrade to an old build of the same version. endFixture, err := atesting.NewFixture( t, - upgradeToVersion, + upgradetest.EnsureSnapshot(define.Version()), atesting.WithFetcher(atesting.ArtifactFetcher()), ) require.NoError(t, err) - t.Logf("Testing Elastic Agent upgrade from %s to %s...", define.Version(), upgradeToVersion) + endVersionInfo, err := endFixture.ExecVersion(ctx) + require.NoError(t, err) + if startVersionInfo.Binary.String() == endVersionInfo.Binary.String() && + startVersionInfo.Binary.Commit == endVersionInfo.Binary.Commit { + t.Skipf("Build under test is the same as the build from the artifacts repository (version: %s) [commit: %s]", + startVersionInfo.Binary.String(), startVersionInfo.Binary.Commit) + } + + t.Logf("Testing Elastic Agent upgrade from %s to %s...", define.Version(), endVersionInfo.Binary.String()) defaultPGP := release.PGP() firstSeven := string(defaultPGP[:7]) @@ -86,10 +94,10 @@ func TestStandaloneUpgradeWithGPGFallbackOneRemoteFailing(t *testing.T) { }) minVersion := upgradetest.Version_8_10_0_SNAPSHOT - fromVersion, err := version.ParseVersion(define.Version()) + currentVersion, err := version.ParseVersion(define.Version()) require.NoError(t, err) - if fromVersion.Less(*minVersion) { + if currentVersion.Less(*minVersion) { t.Skipf("Version %s is lower than min version %s", define.Version(), minVersion) } diff --git a/testing/integration/upgrade_standalone_inprogress.go b/testing/integration/upgrade_standalone_inprogress_test.go similarity index 100% rename from testing/integration/upgrade_standalone_inprogress.go rename to testing/integration/upgrade_standalone_inprogress_test.go diff --git a/testing/integration/upgrade_standalone_retry_test.go b/testing/integration/upgrade_standalone_retry_test.go index d935215e2f4..8286a3f9e7b 100644 --- a/testing/integration/upgrade_standalone_retry_test.go +++ b/testing/integration/upgrade_standalone_retry_test.go @@ -41,18 +41,14 @@ func TestStandaloneUpgradeRetryDownload(t *testing.T) { startFixture, err := define.NewFixture(t, define.Version()) require.NoError(t, err) - // Upgrade to an old build. - upgradeToVersion, err := upgradetest.PreviousMinor(ctx, define.Version()) - require.NoError(t, err) + // Upgrade to an older snapshot build of same version. endFixture, err := atesting.NewFixture( t, - upgradeToVersion, + define.Version(), atesting.WithFetcher(atesting.ArtifactFetcher()), ) require.NoError(t, err) - t.Logf("Testing Elastic Agent upgrade from %s to %s...", define.Version(), upgradeToVersion) - // uses an internal http server that returns bad requests // until it returns a successful request srcPackage, err := endFixture.SrcPackage(ctx) @@ -93,7 +89,8 @@ func TestStandaloneUpgradeRetryDownload(t *testing.T) { }() sourceURI := fmt.Sprintf("http://localhost:%d", port) - err = upgradetest.PerformUpgrade(ctx, startFixture, endFixture, t, upgradetest.WithSourceURI(sourceURI)) + err = upgradetest.PerformUpgrade( + ctx, startFixture, endFixture, t, upgradetest.WithSourceURI(sourceURI)) assert.NoError(t, err) assert.Equal(t, 2, count, "retry request didn't occur") } diff --git a/testing/integration/upgrade_standalone_test.go b/testing/integration/upgrade_standalone_test.go index 4519a6611c3..03652628b27 100644 --- a/testing/integration/upgrade_standalone_test.go +++ b/testing/integration/upgrade_standalone_test.go @@ -9,6 +9,7 @@ package integration import ( "context" "fmt" + "runtime" "testing" "time" @@ -18,6 +19,7 @@ import ( atesting "github.com/elastic/elastic-agent/pkg/testing" "github.com/elastic/elastic-agent/pkg/testing/define" "github.com/elastic/elastic-agent/pkg/testing/tools/testcontext" + "github.com/elastic/elastic-agent/pkg/version" "github.com/elastic/elastic-agent/testing/upgradetest" ) @@ -28,27 +30,49 @@ func TestStandaloneUpgrade(t *testing.T) { Sudo: true, // requires Agent installation }) - ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) - defer cancel() - // test 2 current 8.x version and 1 previous 7.x version + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(1*time.Minute)) + defer cancel() versionList, err := upgradetest.GetUpgradableVersions(ctx, define.Version(), 2, 1) require.NoError(t, err) + endVersion, err := version.ParseVersion(define.Version()) + require.NoError(t, err) for _, startVersion := range versionList { - t.Run(fmt.Sprintf("Upgrade %s to %s", startVersion, define.Version()), func(t *testing.T) { - startFixture, err := atesting.NewFixture( - t, - startVersion.String(), - atesting.WithFetcher(atesting.ArtifactFetcher()), - ) - require.NoError(t, err, "error creating previous agent fixture") - - endFixture, err := define.NewFixture(t, define.Version()) - require.NoError(t, err) - - err = upgradetest.PerformUpgrade(ctx, startFixture, endFixture, t) - assert.NoError(t, err) + unprivilegedAvailable := true + if runtime.GOOS != define.Linux { + // only available on Linux at the moment + unprivilegedAvailable = false + } + if unprivilegedAvailable && (startVersion.Less(*upgradetest.Version_8_13_0) || endVersion.Less(*upgradetest.Version_8_13_0)) { + // only available if both versions are 8.13+ + unprivilegedAvailable = false + } + t.Run(fmt.Sprintf("Upgrade %s to %s (privileged)", startVersion, define.Version()), func(t *testing.T) { + testStandaloneUpgrade(t, startVersion, define.Version(), false) }) + if unprivilegedAvailable { + t.Run(fmt.Sprintf("Upgrade %s to %s (unprivileged)", startVersion, define.Version()), func(t *testing.T) { + testStandaloneUpgrade(t, startVersion, define.Version(), true) + }) + } } } + +func testStandaloneUpgrade(t *testing.T, startVersion *version.ParsedSemVer, endVersion string, unprivileged bool) { + ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) + defer cancel() + + startFixture, err := atesting.NewFixture( + t, + startVersion.String(), + atesting.WithFetcher(atesting.ArtifactFetcher()), + ) + require.NoError(t, err, "error creating previous agent fixture") + + endFixture, err := define.NewFixture(t, endVersion) + require.NoError(t, err) + + err = upgradetest.PerformUpgrade(ctx, startFixture, endFixture, t, upgradetest.WithUnprivileged(unprivileged)) + assert.NoError(t, err) +} diff --git a/testing/integration/upgrade_uninstall_test.go b/testing/integration/upgrade_uninstall_test.go index 2ed3e8d4662..0a493126df6 100644 --- a/testing/integration/upgrade_uninstall_test.go +++ b/testing/integration/upgrade_uninstall_test.go @@ -39,13 +39,11 @@ func TestStandaloneUpgradeUninstallKillWatcher(t *testing.T) { ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute)) defer cancel() - // Start at old version, we want this test to upgrade to our + // Start on a snapshot build, we want this test to upgrade to our // build to ensure that the uninstall will kill the watcher. - startVersion, err := upgradetest.PreviousMinor(ctx, define.Version()) - require.NoError(t, err) startFixture, err := atesting.NewFixture( t, - startVersion, + define.Version(), atesting.WithFetcher(atesting.ArtifactFetcher()), ) require.NoError(t, err) @@ -64,8 +62,7 @@ func TestStandaloneUpgradeUninstallKillWatcher(t *testing.T) { } err = upgradetest.PerformUpgrade( - ctx, startFixture, endFixture, t, - upgradetest.WithPostUpgradeHook(postUpgradeHook)) + ctx, startFixture, endFixture, t, upgradetest.WithPostUpgradeHook(postUpgradeHook)) if !errors.Is(err, ErrPostExit) { require.NoError(t, err) } @@ -83,6 +80,14 @@ func TestStandaloneUpgradeUninstallKillWatcher(t *testing.T) { } require.NoError(t, err) + // watcher needs to start before uninstall, otherwise you can + // get a race condition where watcher hasn't started before + // uninstall does it's PID check to find the watcher. + watcherErr := upgradetest.WaitForWatcher(ctx, 1*time.Minute, time.Second) + if watcherErr != nil { + t.Logf("watcher failed to start: %s", watcherErr) + } + // call uninstall now, do not wait for the watcher to finish running // 8.11+ should always kill the running watcher (if it doesn't uninstall will fail) uninstallCtx, uninstallCancel := context.WithTimeout(context.Background(), 5*time.Minute) diff --git a/testing/upgradetest/upgrader.go b/testing/upgradetest/upgrader.go index 91fe2dafb92..1404a3083d9 100644 --- a/testing/upgradetest/upgrader.go +++ b/testing/upgradetest/upgrader.go @@ -9,13 +9,18 @@ import ( "encoding/json" "errors" "fmt" + "os" "path/filepath" + "runtime" "time" + "github.com/otiai10/copy" + "github.com/elastic/elastic-agent/internal/pkg/agent/application/upgrade/details" v1client "github.com/elastic/elastic-agent/pkg/control/v1/client" v2proto "github.com/elastic/elastic-agent/pkg/control/v2/cproto" atesting "github.com/elastic/elastic-agent/pkg/testing" + "github.com/elastic/elastic-agent/pkg/testing/define" "github.com/elastic/elastic-agent/pkg/version" ) @@ -29,6 +34,7 @@ type CustomPGP struct { type upgradeOpts struct { sourceURI *string + unprivileged *bool skipVerify bool skipDefaultPgp bool customPgp *CustomPGP @@ -44,69 +50,76 @@ type upgradeOpts struct { postUpgradeHook func() error } -type upgradeOpt func(opts *upgradeOpts) +type UpgradeOpt func(opts *upgradeOpts) // WithSourceURI sets a specific --source-uri for the upgrade // command. This doesn't change the verification of the upgrade // the resulting upgrade must still be the same agent provided // in the endFixture variable. -func WithSourceURI(sourceURI string) upgradeOpt { +func WithSourceURI(sourceURI string) UpgradeOpt { return func(opts *upgradeOpts) { opts.sourceURI = &sourceURI } } +// WithUnprivileged sets the install to be explicitly unprivileged. +func WithUnprivileged(unprivileged bool) UpgradeOpt { + return func(opts *upgradeOpts) { + opts.unprivileged = &unprivileged + } +} + // WithSkipVerify sets the skip verify option for upgrade. -func WithSkipVerify(skipVerify bool) upgradeOpt { +func WithSkipVerify(skipVerify bool) UpgradeOpt { return func(opts *upgradeOpts) { opts.skipVerify = skipVerify } } // WithSkipDefaultPgp sets the skip default pgp option for upgrade. -func WithSkipDefaultPgp(skipDefaultPgp bool) upgradeOpt { +func WithSkipDefaultPgp(skipDefaultPgp bool) UpgradeOpt { return func(opts *upgradeOpts) { opts.skipDefaultPgp = skipDefaultPgp } } // WithCustomPGP sets a custom pgp configuration for upgrade. -func WithCustomPGP(customPgp CustomPGP) upgradeOpt { +func WithCustomPGP(customPgp CustomPGP) UpgradeOpt { return func(opts *upgradeOpts) { opts.customPgp = &customPgp } } // WithPreInstallHook sets a hook to be called before install. -func WithPreInstallHook(hook func() error) upgradeOpt { +func WithPreInstallHook(hook func() error) UpgradeOpt { return func(opts *upgradeOpts) { opts.preInstallHook = hook } } // WithPostInstallHook sets a hook to be called before install. -func WithPostInstallHook(hook func() error) upgradeOpt { +func WithPostInstallHook(hook func() error) UpgradeOpt { return func(opts *upgradeOpts) { opts.postInstallHook = hook } } // WithPreUpgradeHook sets a hook to be called before install. -func WithPreUpgradeHook(hook func() error) upgradeOpt { +func WithPreUpgradeHook(hook func() error) UpgradeOpt { return func(opts *upgradeOpts) { opts.preUpgradeHook = hook } } // WithPostUpgradeHook sets a hook to be called before install. -func WithPostUpgradeHook(hook func() error) upgradeOpt { +func WithPostUpgradeHook(hook func() error) UpgradeOpt { return func(opts *upgradeOpts) { opts.postUpgradeHook = hook } } // WithCustomWatcherConfig sets a custom watcher configuration to use. -func WithCustomWatcherConfig(cfg string) upgradeOpt { +func WithCustomWatcherConfig(cfg string) UpgradeOpt { return func(opts *upgradeOpts) { opts.customWatcherCfg = cfg } @@ -116,7 +129,7 @@ func WithCustomWatcherConfig(cfg string) upgradeOpt { // upgrade details that are being set by the Upgrade Watcher. This option is // useful in upgrade tests where the end Agent version does not contain changes // in the Upgrade Watcher whose effects are being asserted upon in PerformUpgrade. -func WithDisableUpgradeWatcherUpgradeDetailsCheck() upgradeOpt { +func WithDisableUpgradeWatcherUpgradeDetailsCheck() UpgradeOpt { return func(opts *upgradeOpts) { opts.disableUpgradeWatcherUpgradeDetailsCheck = true } @@ -128,7 +141,7 @@ func PerformUpgrade( startFixture *atesting.Fixture, endFixture *atesting.Fixture, logger Logger, - opts ...upgradeOpt, + opts ...UpgradeOpt, ) error { // use the passed in options to perform the upgrade // `skipVerify` is by default enabled, because default is to perform a local @@ -169,10 +182,40 @@ func PerformUpgrade( if err != nil { return fmt.Errorf("failed to get parsed start agent build version (%s): %w", startVersionInfo.Binary.String(), err) } + startVersion, err := version.ParseVersion(startVersionInfo.Binary.Version) + if err != nil { + return fmt.Errorf("failed to parse version of starting Agent binary: %w", err) + } endVersionInfo, err := endFixture.ExecVersion(ctx) if err != nil { return fmt.Errorf("failed to get end agent build version info: %w", err) } + endVersion, err := version.ParseVersion(endVersionInfo.Binary.Version) + if err != nil { + return fmt.Errorf("failed to parse version of upgraded Agent binary: %w", err) + } + + // in the unprivileged is unset we adjust it to use unprivileged when the version allows it + // in the case that its explicitly set then we ensure the version supports it + if upgradeOpts.unprivileged == nil { + if !startVersion.Less(*Version_8_13_0) && !endVersion.Less(*Version_8_13_0) && runtime.GOOS == define.Linux { + // both version support --unprivileged + unprivileged := true + upgradeOpts.unprivileged = &unprivileged + logger.Logf("installation of Elastic Agent will use --unprivileged as both start and end version support --unprivileged mode") + } else { + // must be privileged + unprivileged := false + upgradeOpts.unprivileged = &unprivileged + } + } else if *upgradeOpts.unprivileged { + if startVersion.Less(*Version_8_13_0) { + return errors.New("cannot install starting version with --unprivileged (which is default) because the it is older than 8.13") + } + if endVersion.Less(*Version_8_13_0) { + return errors.New("cannot upgrade to ending version as end version doesn't support running with --unprivileged (which is default) because it is older than 8.13") + } + } if startVersionInfo.Binary.Commit == endVersionInfo.Binary.Commit { return fmt.Errorf("target version has the same commit hash %q", endVersionInfo.Binary.Commit) @@ -187,11 +230,6 @@ func PerformUpgrade( // process from the starting version of the agent and not the ending version of the agent. So // even though an 8.12.0 watcher knows to write the upgrade details, prior to 8.10.0 the 8.12.0 // watcher version never executes and the upgrade details are never populated. - endVersion, err := version.ParseVersion(endVersionInfo.Binary.Version) - if err != nil { - return fmt.Errorf("failed to parse version of upgraded Agent binary: %w", err) - } - upgradeOpts.disableUpgradeWatcherUpgradeDetailsCheck = upgradeOpts.disableUpgradeWatcherUpgradeDetailsCheck || endVersion.Less(*version.NewParsedSemVer(8, 12, 0, "", "")) || startParsedVersion.Less(*version.NewParsedSemVer(8, 10, 0, "", "")) @@ -212,6 +250,7 @@ func PerformUpgrade( installOpts := atesting.InstallOpts{ NonInteractive: nonInteractiveFlag, Force: true, + Unprivileged: upgradeOpts.unprivileged, } output, err := startFixture.Install(ctx, &installOpts) if err != nil { @@ -242,11 +281,10 @@ func PerformUpgrade( upgradeCmdArgs := []string{"upgrade", endVersionInfo.Binary.String()} if upgradeOpts.sourceURI == nil { // no --source-uri set so it comes from the endFixture - srcPkg, err := endFixture.SrcPackage(ctx) + sourceURI, err := getSourceURI(ctx, endFixture, *upgradeOpts.unprivileged) if err != nil { return fmt.Errorf("failed to get end agent source package path: %w", err) } - sourceURI := "file://" + filepath.Dir(srcPkg) upgradeCmdArgs = append(upgradeCmdArgs, "--source-uri", sourceURI) } else if *upgradeOpts.sourceURI != "" { // specific --source-uri @@ -509,3 +547,33 @@ func waitUpgradeDetailsState(ctx context.Context, f *atesting.Fixture, expectedS } } } + +func getSourceURI(ctx context.Context, f *atesting.Fixture, unprivileged bool) (string, error) { + srcPkg, err := f.SrcPackage(ctx) + if err != nil { + return "", fmt.Errorf("failed to get source package: %w", err) + } + if unprivileged { + // move the file to temp directory + dir, err := os.MkdirTemp("", "agent-upgrade-*") + if err != nil { + return "", fmt.Errorf("failed to create temp directory: %w", err) + } + err = os.Chmod(dir, 0777) + if err != nil { + return "", fmt.Errorf("failed to chmod temp directory: %w", err) + } + for _, suffix := range []string{"", ".sha512"} { + source := fmt.Sprintf("%s%s", srcPkg, suffix) + dest := fmt.Sprintf("%s%s", filepath.Join(dir, filepath.Base(srcPkg)), suffix) + err = copy.Copy(source, dest, copy.Options{ + PermissionControl: copy.AddPermission(0777), + }) + if err != nil { + return "", fmt.Errorf("failed to copy %s -> %s: %w", source, dest, err) + } + } + srcPkg = filepath.Join(dir, filepath.Base(srcPkg)) + } + return "file://" + filepath.Dir(srcPkg), nil +} diff --git a/testing/upgradetest/versions.go b/testing/upgradetest/versions.go index ea77b6f0ba6..a6a0b7c78b2 100644 --- a/testing/upgradetest/versions.go +++ b/testing/upgradetest/versions.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "sort" + "strings" "github.com/elastic/elastic-agent/pkg/testing/tools" "github.com/elastic/elastic-agent/pkg/version" @@ -29,6 +30,8 @@ var ( Version_8_10_0_SNAPSHOT = version.NewParsedSemVer(8, 10, 0, "SNAPSHOT", "") // Version_8_11_0_SNAPSHOT is the minimum version for uninstall command to kill the watcher upon uninstall Version_8_11_0_SNAPSHOT = version.NewParsedSemVer(8, 11, 0, "SNAPSHOT", "") + // Version_8_13_0 is the minimum version for proper unprivileged execution + Version_8_13_0 = version.NewParsedSemVer(8, 13, 0, "", "") ) // GetUpgradableVersions returns the version that the upgradeToVersion can upgrade from. @@ -135,3 +138,11 @@ func PreviousMinor(ctx context.Context, version string) (string, error) { } return versions[0].String(), nil } + +// EnsureSnapshot ensures that the version string is a snapshot version. +func EnsureSnapshot(version string) string { + if !strings.HasSuffix(version, "-SNAPSHOT") { + version += "-SNAPSHOT" + } + return version +} diff --git a/version/helper.go b/version/helper.go index 86ace2dde7f..2bec8781884 100644 --- a/version/helper.go +++ b/version/helper.go @@ -31,6 +31,17 @@ var ( const PackageVersionFileName = "package.version" +var versionInitError error + +func init() { + versionInitError = InitVersionInformation() +} + +// InitVersionError returns any error that might have occurred during package init +func InitVersionError() error { + return versionInitError +} + // InitVersionInformation initialize the package version string reading from the // corresponding file. This function is not thread-safe and should be called once // before any calls to Version() has been done