From 2865333dbd6f84d2f2f2b10e86b80928f7a61647 Mon Sep 17 00:00:00 2001 From: Jon Cahill-Torre Date: Thu, 21 Nov 2024 17:43:34 +0000 Subject: [PATCH 1/7] docs: import v3-documentation docs --- site/content/_index.md | 10 +- .../NGINX-agent-v2/overview.md => about.md} | 46 +- site/content/changelog.md | 2 +- site/content/configuration/_index.md | 7 - .../configuration/configuration-overview.md | 286 ------- site/content/contribute/_index.md | 9 +- site/content/contribute/community.md | 9 +- .../contribute/dev-environment-setup.md | 55 +- .../contribute/start-mock-interface.md | 90 ++ site/content/how-to/_index.md | 6 + site/content/how-to/configuration-overview.md | 290 +++++++ .../configure-agent-group.md} | 33 +- .../connect-management-plane.md | 14 +- site/content/how-to/enable-interfaces.md | 73 ++ .../encrypt-communication.md | 25 +- site/content/how-to/export-metrics.md | 45 + site/content/install-upgrade/_index.md | 6 + .../container-environments/_index.md | 6 + .../container-environments/docker-images.md | 41 +- .../container-environments/docker-support.md | 16 +- site/content/install-upgrade/install.md | 784 ++++++++++++++++++ site/content/install-upgrade/migrate-v3.md | 44 + site/content/install-upgrade/uninstall.md | 145 ++++ .../upgrade.md | 13 +- site/content/installation-upgrade/_index.md | 6 - .../container-environments/_index.md | 6 - .../installation-github.md | 53 -- .../installation-upgrade/installation-oss.md | 349 -------- .../installation-upgrade/installation-plus.md | 453 ---------- .../content/installation-upgrade/uninstall.md | 146 ---- site/content/metrics.md | 5 + site/content/overview.md | 69 -- .../NGINX-agent-v2/changelog.md | 211 ----- .../NGINX-agent-v2/configuration/_index.md | 7 - .../NGINX-agent-v2/contribute/_index.md | 7 - .../NGINX-agent-v2/contribute/community.md | 24 - .../contribute/dev-environment-setup.md | 65 -- .../installation-upgrade/_index.md | 6 - .../container-environments/_index.md | 6 - .../installation-upgrade/getting-started.md | 181 ---- site/content/previous-versions/_index.md | 6 - site/content/support.md | 15 + site/content/technical-specifications.md | 23 +- .../NGINX-agent-v2 => v2}/_index.md | 5 +- site/content/v2/changelog.md | 264 ++++++ site/content/v2/configuration/_index.md | 6 + .../configuration/configuration-overview.md | 0 .../configure-nginx-agent-group.md | 0 .../configuration/encrypt-communication.md | 0 .../content/v2/installation-upgrade/_index.md | 7 + .../container-environments/_index.md | 6 + .../container-environments/docker-images.md | 2 +- .../container-environments/docker-support.md | 2 +- .../installation-upgrade/getting-started.md | 9 +- .../installation-github.md | 0 .../installation-upgrade/installation-oss.md | 0 .../installation-upgrade/installation-plus.md | 0 .../installation-upgrade/uninstall.md | 0 .../installation-upgrade/upgrade.md | 0 site/content/v2/metrics.md | 10 + .../technical-specifications.md | 19 +- 61 files changed, 1962 insertions(+), 2061 deletions(-) rename site/content/{previous-versions/NGINX-agent-v2/overview.md => about.md} (68%) delete mode 100644 site/content/configuration/_index.md delete mode 100644 site/content/configuration/configuration-overview.md create mode 100644 site/content/contribute/start-mock-interface.md create mode 100644 site/content/how-to/_index.md create mode 100644 site/content/how-to/configuration-overview.md rename site/content/{configuration/configure-nginx-agent-group.md => how-to/configure-agent-group.md} (84%) rename site/content/{configuration => how-to}/connect-management-plane.md (91%) create mode 100644 site/content/how-to/enable-interfaces.md rename site/content/{configuration => how-to}/encrypt-communication.md (95%) create mode 100644 site/content/how-to/export-metrics.md create mode 100644 site/content/install-upgrade/_index.md create mode 100644 site/content/install-upgrade/container-environments/_index.md rename site/content/{installation-upgrade => install-upgrade}/container-environments/docker-images.md (90%) rename site/content/{installation-upgrade => install-upgrade}/container-environments/docker-support.md (84%) create mode 100644 site/content/install-upgrade/install.md create mode 100644 site/content/install-upgrade/migrate-v3.md create mode 100644 site/content/install-upgrade/uninstall.md rename site/content/{installation-upgrade => install-upgrade}/upgrade.md (92%) delete mode 100644 site/content/installation-upgrade/_index.md delete mode 100644 site/content/installation-upgrade/container-environments/_index.md delete mode 100644 site/content/installation-upgrade/installation-github.md delete mode 100644 site/content/installation-upgrade/installation-oss.md delete mode 100644 site/content/installation-upgrade/installation-plus.md delete mode 100644 site/content/installation-upgrade/uninstall.md create mode 100644 site/content/metrics.md delete mode 100644 site/content/overview.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/changelog.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/configuration/_index.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/contribute/_index.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/contribute/community.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/contribute/dev-environment-setup.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/installation-upgrade/_index.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/_index.md delete mode 100644 site/content/previous-versions/NGINX-agent-v2/installation-upgrade/getting-started.md delete mode 100644 site/content/previous-versions/_index.md create mode 100644 site/content/support.md rename site/content/{previous-versions/NGINX-agent-v2 => v2}/_index.md (72%) create mode 100644 site/content/v2/changelog.md create mode 100644 site/content/v2/configuration/_index.md rename site/content/{previous-versions/NGINX-agent-v2 => v2}/configuration/configuration-overview.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/configuration/configure-nginx-agent-group.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/configuration/encrypt-communication.md (100%) create mode 100644 site/content/v2/installation-upgrade/_index.md create mode 100644 site/content/v2/installation-upgrade/container-environments/_index.md rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/container-environments/docker-images.md (99%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/container-environments/docker-support.md (92%) rename site/content/{ => v2}/installation-upgrade/getting-started.md (97%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/installation-github.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/installation-oss.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/installation-plus.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/uninstall.md (100%) rename site/content/{previous-versions/NGINX-agent-v2 => v2}/installation-upgrade/upgrade.md (100%) create mode 100644 site/content/v2/metrics.md rename site/content/{previous-versions/NGINX-agent-v2 => v2}/technical-specifications.md (87%) diff --git a/site/content/_index.md b/site/content/_index.md index ac81454ba1..b3764d9169 100644 --- a/site/content/_index.md +++ b/site/content/_index.md @@ -1,6 +1,6 @@ --- -title: "Welcome to the NGINX Agent documentation" -description: "NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus instance." -linkTitle: "NGINX Agent" -menu: docs ---- \ No newline at end of file +title: "NGINX Agent Documentation" +weight: 900 +--- + +NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus instance \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/overview.md b/site/content/about.md similarity index 68% rename from site/content/previous-versions/NGINX-agent-v2/overview.md rename to site/content/about.md index a46f1b1dee..02778fc1d6 100644 --- a/site/content/previous-versions/NGINX-agent-v2/overview.md +++ b/site/content/about.md @@ -1,14 +1,12 @@ --- -title: "Overview" -draft: false +title: "About" weight: 100 toc: true -tags: [ "docs" ] -docs: "DOCS-1091" -categories: ["configuration"] -doctypes: ["task"] +docs: DOCS-000 --- +This page provides a brief overview of what F5 NGINX Agent is, and how it works. + ## Overview NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus instance. It enables: @@ -17,37 +15,57 @@ NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus insta - Collection and reporting of real-time NGINX performance and operating system metrics - Notifications of NGINX events +[OpenTelemetry](https://opentelemetry.io/) support comes with NGINX Agent v3, and the ability to [export the metrics data]({{< relref "/how-to/export-metrics.md" >}}) for use in other applications. + +For an overview of the metrics available from NGINX Agent, read the following topics: + +- [OpenTelemetry metrics]({{< relref "/metrics.md" >}}) (Agent v3) +- [Metrics]({{< relref "/v2/metrics.md" >}}) (Agent v2) -{{< img src="grafana-dashboard-example.png" caption="Grafana dashboard showing metrics reported by NGINX Agent" alt="Grafana dashboard showing metrics reported by NGINX Agent" width="99%">}} -## How it Works +{{< img src="grafana-dashboard-example.png" caption="A Grafana dashboard displaying metrics reported by NGINX Agent." alt="A Grafana dashboard displaying metrics reported by NGINX Agent.">}} + +--- -NGINX Agent runs as a companion process on a system running NGINX. It provides gRPC and REST interfaces for configuration management and metrics collection from the NGINX process and operating system. NGINX Agent enables remote interaction with NGINX using common Linux tools and unlocks the ability to build sophisticated monitoring and control systems that can manage large collections of NGINX instances. +## How it works + +NGINX Agent runs as a companion process on a system running NGINX. It provides gRPC and REST interfaces for configuration management and metrics collection from the NGINX process and operating system. + +NGINX Agent enables remote interaction with NGINX using common Linux tools and unlocks the ability to build sophisticated monitoring and control systems that can manage large collections of NGINX instances. {{< img src="agent-flow.png" caption="How Agent works" alt="How NGINX Agent works" width="99%">}} -## Configuration Management +## Configuration management NGINX Agent provides an API interface for submission of updated configuration files. Upon receipt of a new file, it checks the output of `nginx -V` to determine the location of existing configurations. It then validates the new configuration with `nginx -t` before applying it via a signal HUP to the NGINX master process. -## Collecting Metrics +For additional information, view the [Configuration overview]({{< relref "/how-to/configuration-overview.md" >}}) topic. + +--- + +## Collecting metrics NGINX Agent interfaces with NGINX process information and parses NGINX logs to calculate and report metrics. When interfacing with NGINX Plus, NGINX Agent pulls relevant information from the NGINX Plus API. Reported metrics may be aggregated by [Prometheus](https://prometheus.io/) and visualized with tools like [Grafana](https://grafana.com/). +--- + ### NGINX Open Source When running alongside an open source instance of NGINX, NGINX Agent requires that NGINX Access and Error logs are turned on and contain all default variables. +--- + ### NGINX Plus -For NGINX Agent to work properly with an NGINX Plus instance, the API needs to be configured in that instance's nginx.conf. See [Instance Metrics Overview](https://docs.nginx.com/nginx-management-suite/nim/about/overview-metrics/) for more details. Once NGINX Plus is configured with the `/api/` endpoint, the Agent will automatically use it on startup. +For NGINX Agent to work properly with an NGINX Plus instance, the API needs to be configured in that instance's nginx.conf. View the [Instance Metrics Overview](https://docs.nginx.com/nginx-management-suite/nim/about/overview-metrics/) topic for more details. Once NGINX Plus is configured with the `/api/` endpoint, the Agent will automatically use it on startup. + +--- -## Event Notifications +## Event notifications NGINX Agent allows a gRPC connected control system to register a listener for a specific event. The control mechanism is then invoked when NGINX Agent sends an associated system signal. The source of a notification can be either the NGINX instance or NGINX Agent itself. Here's a list of currently supported events: - {{< raw-html>}}
{{}} {{}} | Event | Description | diff --git a/site/content/changelog.md b/site/content/changelog.md index 8da814d0ea..07f23553fb 100644 --- a/site/content/changelog.md +++ b/site/content/changelog.md @@ -1,6 +1,6 @@ --- title: "Changelog" -weight: 1200 +weight: 700 toc: true --- diff --git a/site/content/configuration/_index.md b/site/content/configuration/_index.md deleted file mode 100644 index 3d1fdf4e34..0000000000 --- a/site/content/configuration/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Configuration" -description: "Learn how to configure NGINX Agent." -linkTitle: "Configuration" -weight: "400" -menu: docs ---- \ No newline at end of file diff --git a/site/content/configuration/configuration-overview.md b/site/content/configuration/configuration-overview.md deleted file mode 100644 index 66d09b3c71..0000000000 --- a/site/content/configuration/configuration-overview.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: "Configuration overview" -draft: false -weight: 100 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -The following sections explain how to configure NGINX Agent using configuration files, CLI flags, and environment variables. - -{{}} - -- NGINX Agent interprets configuration values set by configuration files, CLI flags, and environment variables in the following priorities: - - 1. CLI flags overwrite configuration files and environment variable values. - 2. Environment variables overwrite configuration file values. - 3. Config files are the lowest priority and config settings are superseded if either of the other options is used. - -- You must open any required firewall ports or add SELinux/AppArmor rules for the ports and IPs you want to use. - -{{}} - -### Configure with Config Files - -The default locations of configuration files for NGINX Agent are `/etc/nginx-agent/nginx-agent.conf` and `/var/lib/nginx-agent/agent-dynamic.conf`. The `agent-dynamic.conf` file default location is different for FreeBSD which is located `/var/db/nginx-agent/agent-dynamic.conf`. These files have comments at the top indicating their purpose. - -Examples of the configuration files are provided below: - -
- example nginx-agent.conf - -{{}} -In the following example `nginx-agent.conf` file, you can change the `server.host` and `server.grpcPort` to connect to the control/management plane. -{{}} - -```nginx {hl_lines=[13]} -# -# /etc/nginx-agent/nginx-agent.conf -# -# Configuration file for NGINX Agent. -# -# This file tracks agent configuration values that are meant to be statically set. There -# are additional NGINX Agent configuration values that are set via the API and agent install script -# which can be found in /etc/nginx-agent/agent-dynamic.conf. - -# specify the server grpc port to connect to -server: - # host of the control plane - host: - grpcPort: 443 -# tls options -tls: - # enable tls in the nginx-agent setup for grpcs - # default to enable to connect with secure connection but without client cert for mtls - enable: true - # controls whether the server certificate chain and host name are verified. - # for production use, see instructions for configuring TLS - skip_verify: false -log: - # set log level (panic, fatal, error, info, debug, trace; default "info") - level: info - # set log path. if empty, don't log to file. - path: /var/log/nginx-agent/ -nginx: - # path of NGINX logs to exclude - exclude_logs: "" - # Set to true when NGINX configuration should contain no warnings when performing a configuration apply (nginx -t is used to carry out this check) - treat_warnings_as_errors: false # Default is false -# data plane status message / 'heartbeat' -dataplane: - status: - # poll interval for dataplane status - the frequency the agent will query the dataplane for changes - poll_interval: 30s - # report interval for dataplane status - the maximum duration to wait before syncing dataplane information if no updates have been observed - report_interval: 24h -metrics: - # specify the size of a buffer to build before sending metrics - bulk_size: 20 - # specify metrics poll interval - report_interval: 1m - collection_interval: 15s - mode: aggregated - -# OSS NGINX default config path -# path to aux file dirs can also be added -config_dirs: "/etc/nginx:/usr/local/etc/nginx" - -# Internal queue size -queue_size: 100 - -extensions: - - nginx-app-protect - -# Enable reporting NGINX App Protect details to the control plane. -nginx_app_protect: - # Report interval for NGINX App Protect details - the frequency NGINX Agent checks NGINX App Protect for changes. - report_interval: 15s - # Enable precompiled publication from the NGINX Management Suite (true) or perform compilation on the data plane host (false). - precompiled_publication: true -``` - -
- - -
- example dynamic-agent.conf - -{{}} -Default location in Linux environments: `/var/lib/nginx-agent/agent-dynamic.conf` - -Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.conf` -{{}} - -```yaml -# Dynamic configuration file for NGINX Agent. -# -# The purpose of this file is to track agent configuration -# values that can be dynamically changed via the API and the agent install script. -# You may edit this file, but API calls that modify the tags on this system will -# overwrite the tag values in this file. -# -# The agent configuration values that API calls can modify are as follows: -# - tags -# -# The agent configuration value that the agent install script can modify are as follows: -# - instance_group - -instance_group: devenv-group -tags: - - devenv - - test -``` - -
- - -### NGINX Agent CLI Flags & Usage {#nginx-agent-cli-flags-usage} - -This section displays the configurable options for NGINX Agent that can be set with CLI flags. See the CLI flags and their uses in the figure below: - -
- NGINX Agent CLI flags & usage - -```text -Usage: - nginx-agent [flags] - nginx-agent [command] - -Available Commands: - completion Generate completion script. - help Help about any command - -Flags: - --api-cert string The cert used by the Agent API. - --api-host string The host used by the Agent API. (default "127.0.0.1") - --api-key string The key used by the Agent API. - --api-port int The desired port to use for nginx-agent to expose for HTTP traffic. - --config-dirs string Defines the paths that you want to grant nginx-agent read/write access to. This key is formatted as a string and follows Unix PATH format. (default "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms") - --dataplane-report-interval duration The amount of time the agent will report on the dataplane. After this period of time it will send a snapshot of the dataplane information. (default 24h0m0s) - --dataplane-status-poll-interval duration The frequency the agent will check the dataplane for changes. Used as a "heartbeat" to keep the gRPC connections alive. (default 30s) - --display-name string The instance's 'name' value. - --dynamic-config-path string Defines the path of the Agent dynamic config file. (default "/var/lib/nginx-agent/agent-dynamic.conf") - --features strings A comma-separated list of features enabled for the agent. (default [registration,nginx-config-async,nginx-ssl-config,nginx-counting,metrics,dataplane-status,process-watcher,file-watcher,activity-events,agent-api]) - -h, --help help for nginx-agent - --ignore-directives strings A comma-separated list of ignoring directives which contain sensitive info. - --instance-group string The instance's 'group' value. - --log-level string The desired verbosity level for logging messages from nginx-agent. Available options, in order of severity from highest to lowest, are: panic, fatal, error, info, debug, and trace. (default "info") - --log-path string The path to output log messages to. If the default path doesn't exist, log messages are output to stdout/stderr. - --metrics-bulk-size int The amount of metrics reports collected before sending the data back to the server. (default 20) - --metrics-collection-interval duration Sets the interval, in seconds, at which metrics are collected. (default 15s) - --metrics-mode string Sets the desired metrics collection mode: streaming or aggregation. (default "aggregated") - --metrics-report-interval duration The polling period specified for a single set of metrics being collected. (default 1m0s) - --nginx-config-reload-monitoring-period duration The duration NGINX Agent will monitor error logs after a NGINX reload (default 10s) - --nginx-exclude-logs string One or more NGINX access log paths that you want to exclude from metrics collection. This key is formatted as a string and multiple values should be provided as a comma-separated list. - --nginx-socket string The NGINX Plus counting unix socket location. (default "unix:/var/run/nginx-agent/nginx.sock") - --nginx-treat-warnings-as-errors On nginx -t, treat warnings as failures on configuration application. - --queue-size int The size of the NGINX Agent internal queue. - --server-command string The name of the command server sent in the tls configuration. - --server-grpcport int The desired GRPC port to use for nginx-agent traffic. - --server-host string The IP address of the server host. IPv4 addresses and hostnames are supported. - --server-metrics string The name of the metrics server sent in the tls configuration. - --server-token string An authentication token that grants nginx-agent access to the commander and metrics services. Auto-generated by default. (default "e202f883-54c6-4702-be15-3ba6e507879a") - --tags strings A comma-separated list of tags to add to the current instance or machine, to be used for inventory purposes. - --tls-ca string The path to the CA certificate file to use for TLS. - --tls-cert string The path to the certificate file to use for TLS. - --tls-enable Enables TLS for secure communications. - --tls-key string The path to the certificate key file to use for TLS. - --tls-skip-verify Only intended for demonstration, sets InsecureSkipVerify for gRPC TLS credentials - -v, --version version for nginx-agent - -Use "nginx-agent [command] --help" for more information about a command. -``` - -
- -#### NGINX Agent Config Dirs Option - -Use the `--config-dirs` command-line option, or the `config_dirs` key in the `nginx-agent.conf` file, to identify the directories NGINX Agent can read from or write to. This setting also defines the location to which you can upload config files when using a control/management plane. NGINX Agent cannot write to directories outside the specified location when updating a config and cannot upload files to directories outside of the configured location. -NGINX Agent follows NGINX configuration directives to file paths outside the designated directories and reads certificates' metadata. NGINX Agent uses the following directives: - -- [`ssl_certificate`](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) - -#### NGINX Agent Dynamic Config Path Option - -Use the `--dynamic-config-path` command-line option to set the location of the dynamic config file. This setting also requires you to move your dynamic config to the new path, or create a new dynamic config file at the specified location. - -Default location in Linux environments: `/var/lib/nginx-agent/agent-dynamic.conf` - -Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.conf` - -### NGINX Agent Environment Variables - -This section displays the configurable options for NGINX Agent that can be set with environment variables. A list of the configurable environment variables can be seen below: - -
- NGINX Agent Environment Variables - -```text -- NMS_INSTANCE_GROUP -- NMS_DISPLAY_NAME -- NMS_FEATURES -- NMS_LOG_LEVEL -- NMS_LOG_PATH -- NMS_PATH -- NMS_METRICS_COLLECTION_INTERVAL -- NMS_METRICS_MODE -- NMS_METRICS_BULK_SIZE -- NMS_METRICS_REPORT_INTERVAL -- NMS_NGINX_EXCLUDE_LOGS -- NMS_NGINX_SOCKET -- NMS_NGINX_TREAT_WARNINGS_AS_ERRORS -- NMS_SERVER_GRPCPORT -- NMS_SERVER_HOST -- NMS_SERVER_TOKEN -- NMS_SERVER_COMMAND -- NMS_SERVER_METRICS -- NMS_TAGS -- NMS_TLS_CA -- NMS_TLS_CERT -- NMS_TLS_ENABLE -- NMS_TLS_KEY -- NMS_TLS_SKIP_VERIFY -- NMS_CONFIG_DIRS -- NMS_QUEUE_SIZE -- NMS_DATAPLANE_REPORT_INTERVAL -- NMS_DATAPLANE_STATUS_POLL_INTERVAL -``` -
- -### NGINX Agent Log Rotation - -By default, NGINX Agent rotates logs daily using logrotate with the following configuration: - -
- NGINX Agent Logrotate Configuration - -``` yaml -/var/log/nginx-agent/*.log -{ - # log files are rotated every day - daily - # log files are rotated if they grow bigger than 5M - size 5M - # truncate the original log file after creating a copy - copytruncate - # remove rotated logs older than 10 days - maxage 10 - # log files are rotated 10 times before being removed - rotate 10 - # old log files are compressed - compress - # if the log file is missing it will go on to the next one without issuing an error message - missingok - # do not rotate the log if it is empty - notifempty -} -``` -
- -If you need to make changes to the default configuration you can update the file here `/etc/logrotate.d/nginx-agent` - -For more detail on logrotate configuration see [Logrotate Configuration Options](https://linux.die.net/man/8/logrotate) diff --git a/site/content/contribute/_index.md b/site/content/contribute/_index.md index dc79b629a7..9eebf54038 100644 --- a/site/content/contribute/_index.md +++ b/site/content/contribute/_index.md @@ -1,7 +1,6 @@ --- title: "Contribute" -description: "Learn about the NGINX Agent community and contribute to the project." -linkTitle: "Contribute" -menu: docs -weight: "500" ---- \ No newline at end of file +weight: 600 +--- + +Learn about the NGINX Agent community and how to contribute to the project. \ No newline at end of file diff --git a/site/content/contribute/community.md b/site/content/contribute/community.md index 4eea3d22a5..3fbf8f1615 100644 --- a/site/content/contribute/community.md +++ b/site/content/contribute/community.md @@ -1,13 +1,12 @@ --- title: "Community and contribution" -draft: false -weight: 100 toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] +weight: 100 +docs: DOCS-000 --- +This topic describes the various ways you can get involved with the F5 NGINX Agent project. + # Community - Our [Slack channel #nginx-agent](https://nginxcommunity.slack.com/), is the go-to place to start asking questions and sharing your thoughts. diff --git a/site/content/contribute/dev-environment-setup.md b/site/content/contribute/dev-environment-setup.md index f756ef7fcd..d56c064cba 100644 --- a/site/content/contribute/dev-environment-setup.md +++ b/site/content/contribute/dev-environment-setup.md @@ -1,64 +1,61 @@ --- -title: "Development environment Setup" -draft: false -weight: 200 +title: "Development environment setup" toc: true -tags: [ "docs" ] -categories: ["development"] -doctypes: ["task"] +weight: 200 +docs: DOCS-000 --- ## Overview -Learn how to setup a Development Environment for NGINX Agent. +This page describes how to configure a development environment for F5 NGINX Agent. + +While most Linux or FreeBSD operating systems can be used to contribute to the NGINX Agent project, the following steps have been designed for Ubuntu. + +Ubuntu is the recommended operating system for development, as it comes with most packages requires to build and run NGINX Agent. + +## Before you begin -## Select an Operating System +To begin this task, you will require the following: -While most Linux or FreeBSD operating systems can be used to contribute to the NGINX Agent project, the following steps have been designed for Ubuntu. Ubuntu is packaged with most libraries required to build and run NGINX Agent, and is the recommended platform for NGINX Agent development. +- A [working NGINX Agent instance]({{< ref "/install-upgrade/install.md" >}}). +- A [Go installation](https://go.dev/dl/) of version 1.22.2 or newer. +- A [Protocol Buffer Compiler](https://grpc.io/docs/protoc-installation/) installation. -## Install NGINX +You will also need a copy of the NGINX Agent repository, which you can clone using `git`: -Follow the steps in the [Installation]({{< relref "/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX and NGINX Agent. +```shell +git clone git@github.com:nginx/agent.git +``` -## Clone the NGINX Agent Repository +Read [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for more information -Using your preferred method, clone the NGINX Agent repository into your development directory. See [Cloning a GitHub Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for additional help. +Follow the steps in the [Installation]({{< relref "/install-upgrade/install.md" >}}) topic to install NGINX Agent. -## Installing Prerequisite Packages +## Install prerequisite packages Depending on the operating system distribution, it may be necessary to install the following packages in order to build NGINX Agent. Change to the NGINX Agent source directory: -```bash +```shell cd /agent ``` Install Make: -```bash +```shell sudo apt install make ``` -NGINX Agent is written in Go. You may [download Go](https://go.dev/doc/install) and follow installation instructions on the same page or run: -```bash -sudo apt install golang-go -``` - -Install Protoc: -```bash -sudo apt install -y protobuf-compiler -``` - Install NGINX Agent tools and dependencies: Before starting development on NGINX Agent, it is important to download and install the necessary tool and dependencies required by NGINX Agent. You can do this by running the following `make` command: -```bash +```shell make install-tools deps ``` -## Building NGINX Agent from Source Code +## Build NGINX Agent from source code Run the following commands to build and run NGINX Agent: -```bash +```shell make build sudo make run ``` diff --git a/site/content/contribute/start-mock-interface.md b/site/content/contribute/start-mock-interface.md new file mode 100644 index 0000000000..2c148de78e --- /dev/null +++ b/site/content/contribute/start-mock-interface.md @@ -0,0 +1,90 @@ +--- +title: Start mock control plane interface +toc: true +weight: 300 +docs: DOCS-000 +--- + +This document describes how to configure and run F5 NGINX Agent using a mock interface ("control plane") for NGINX Agent to report to. + +The mock interface is useful when developing NGINX Agent, as it allows you to view what metrics are being reported. + +## Before you begin + +To begin this task, you will require the following: + +- A [working NGINX Agent instance]({{< ref "/install-upgrade/install.md" >}}). +- A [Go installation](https://go.dev/dl/) of version 1.22.2 or newer. +- A [go-swagger](https://goswagger.io/go-swagger/install/) installation. + +You will also need a copy of the NGINX Agent repository, which you can clone using `git`: + +```shell +git clone git@github.com:nginx/agent.git +``` + +Read [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for more information. + +## Start the gRPC mock control plane + +Start the mock control plane by running the following command from the `agent` source code root directory: + +```shell +go run sdk/examples/server.go +``` +```text +INFO[0000] http listening at 54790 # mock control plane port +INFO[0000] grpc listening at 54789 # grpc control plane port which NGINX Agent will report to +``` + +The mock control plane can use either gRPC or REST protocols to communicate with NGINX Agent. + +To enable them, view the [Enable gRPC and REST interfaces]({{< relref "/how-to/enable-interfaces.md" >}}) topic. + +## Launch Swagger UI + +To launch the Swagger UI for the REST interface run the following command: + +```shell +make launch-swagger-ui +``` + +## Start NGINX Agent + +Open another terminal window and start NGINX Agent. Issue the following command from the `agent` source code root directory. + +```shell +sudo make run +``` +```text +WARN[0000] Log level is info +INFO[0000] setting displayName to XXX +INFO[0000] NGINX Agent at with pid 12345, clientID=XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX name=XXX +INFO[0000] NginxBinary initializing +INFO[0000] Commander initializing +INFO[0000] Comms initializing +INFO[0000] OneTimeRegistration initializing +INFO[0000] Registering XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX +INFO[0000] Metrics initializing +INFO[0000] MetricsThrottle initializing +INFO[0000] DataPlaneStatus initializing +INFO[0000] MetricsThrottle waiting for report ready +INFO[0000] Metrics waiting for handshake to be completed +INFO[0000] ProcessWatcher initializing +INFO[0000] Extensions initializing +INFO[0000] FileWatcher initializing +INFO[0000] FileWatchThrottle initializing +INFO[0001] Events initializing +INFO[0001] OneTimeRegistration completed +``` + +Open a web browser to view the mock control plane at [http://localhost:54790](http://localhost:54790). The following links will be shown in the web interface: + +- **registered** - shows registration information of the data plane +- **nginxes** - lists the nginx instances on the data plane +- **configs** - shows the protobuf payload for NGINX configuration sent to the management plane +- **configs/chunked** - shows the split-up payloads sent to the management plane +- **configs/raw** - shows the actual configuration as it would live on the data plane +- **metrics** - shows a buffer of metrics sent to the management plane (similar to what will be sent back in the REST API) + +For more NGINX Agent use cases, refer to the [NGINX Agent SDK examples](https://github.com/nginx/agent/tree/main/sdk/examples). \ No newline at end of file diff --git a/site/content/how-to/_index.md b/site/content/how-to/_index.md new file mode 100644 index 0000000000..3f01dc82b9 --- /dev/null +++ b/site/content/how-to/_index.md @@ -0,0 +1,6 @@ +--- +title: "How-to guides" +weight: 500 +--- + +Learn how to configure NGINX Agent \ No newline at end of file diff --git a/site/content/how-to/configuration-overview.md b/site/content/how-to/configuration-overview.md new file mode 100644 index 0000000000..26c2a41b27 --- /dev/null +++ b/site/content/how-to/configuration-overview.md @@ -0,0 +1,290 @@ +--- +title: "Configuration overview" +toc: true +weight: 100 +docs: DOCS-1229 +--- + +This page describes how to configure F5 NGINX Agent using configuration files, CLI (Command line interface) flags, and environment variables. + +{{}} + +- NGINX Agent interprets configuration values set by configuration files, CLI flags, and environment variables in the following priorities: + + 1. CLI flags overwrite configuration files and environment variable values. + 2. Environment variables overwrite configuration file values. + 3. Config files are the lowest priority and config settings are superseded if either of the other options is used. + +- You must open any required firewall ports or add SELinux/AppArmor rules for the ports and IPs you want to use. + +{{}} + +## Configuration files + +The default locations of configuration files for NGINX Agent are `/etc/nginx-agent/nginx-agent.conf` and `/var/lib/nginx-agent/agent-dynamic.conf`. The `agent-dynamic.conf` file default location is different for FreeBSD which is located `/var/db/nginx-agent/agent-dynamic.conf`. These files have comments at the top indicating their purpose. + +Examples of the configuration files are provided below: + +
+ example nginx-agent.conf + +{{}} +In the following example `nginx-agent.conf` file, you can change the `server.host` and `server.grpcPort` to connect to the control plane. +{{}} + +```nginx {hl_lines=[13]} +# +# /etc/nginx-agent/nginx-agent.conf +# +# Configuration file for NGINX Agent. +# +# This file tracks agent configuration values that are meant to be statically set. There +# are additional NGINX Agent configuration values that are set via the API and agent install script +# which can be found in /etc/nginx-agent/agent-dynamic.conf. + +# specify the server grpc port to connect to +server: + # host of the control plane + host: + grpcPort: 443 + backoff: # note: default values are prepopulated + initial_interval: 100ms # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + randomization_factor: 0.10 # Add the appropriate float value here, e.g., 0.10 + multiplier: 1.5 # Add the appropriate float value here, e.g., 1.5 + max_interval: 1m # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + max_elapsed_time: 0 # Add the appropriate duration value here, e.g., "0" for indefinite "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour +# tls options +tls: + # enable tls in the nginx-agent setup for grpcs + # default to enable to connect with secure connection but without client cert for mtls + enable: true + # controls whether the server certificate chain and host name are verified. + # for production use, see instructions for configuring TLS + skip_verify: false +log: + # set log level (panic, fatal, error, info, debug, trace; default "info") + level: info + # set log path. if empty, don't log to file. + path: /var/log/nginx-agent/ +nginx: + # path of NGINX logs to exclude + exclude_logs: "" + # Set to true when NGINX configuration should contain no warnings when performing a configuration apply (nginx -t is used to carry out this check) + treat_warnings_as_errors: false # Default is false +# data plane status message / 'heartbeat' +dataplane: + status: + # poll interval for dataplane status - the frequency the NGINX Agent will query the dataplane for changes + poll_interval: 30s + # report interval for dataplane status - the maximum duration to wait before syncing dataplane information if no updates have been observed + report_interval: 24h +metrics: + # specify the size of a buffer to build before sending metrics + bulk_size: 20 + # specify metrics poll interval + report_interval: 1m + collection_interval: 15s + mode: aggregated + backoff: # note: default values are prepopulated + initial_interval: 100ms # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + randomization_factor: 0.10 # Add the appropriate float value here, e.g., 0.10 + multiplier: 1.5 # Add the appropriate float value here, e.g., 1.5 + max_interval: 1m # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + max_elapsed_time: 0 # Add the appropriate duration value here, e.g., "0" for indefinite "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + +# OSS NGINX default config path +# path to aux file dirs can also be added +config_dirs: "/etc/nginx:/usr/local/etc/nginx" + +# Internal queue size +queue_size: 100 + +extensions: + - nginx-app-protect + +# Enable reporting NGINX App Protect details to the control plane. +nginx_app_protect: + # Report interval for NGINX App Protect details - the frequency NGINX Agent checks NGINX App Protect for changes. + report_interval: 15s + # Enable precompiled publication from the NGINX Management Suite (true) or perform compilation on the data plane host (false). + precompiled_publication: true +``` + +
+ + +
+ example dynamic-agent.conf + +{{}} +Default location in Linux environments: `/var/lib/nginx-agent/agent-dynamic.conf` + +Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.conf` +{{}} + +```yaml +# Dynamic configuration file for NGINX Agent. +# +# The purpose of this file is to track agent configuration +# values that can be dynamically changed via the API and the agent install script. +# You may edit this file, but API calls that modify the tags on this system will +# overwrite the tag values in this file. +# +# The agent configuration values that API calls can modify are as follows: +# tags: +# - dev +# - qa +# +# The agent configuration value that the agent install script can modify are as follows: +# instance_group: my-instance-group + +instance_group: my-instance-group +tags: + - dev + - qa +``` + +
+ +## CLI flags and environment variables + +This section details the CLI flags and corresponding environment variables used to configure the NGINX Agent. + +### CLI flags + +```sh +nginx-agent [flags] +``` + +### Environment variables + +```sh +export ENV_VARIABLE_NAME="value" +nginx-agent +``` + +### Flag and environment arguments + +{{< warning >}} + +Before version 2.35.0, the environment variables were prefixed with `NMS_` instead of `NGINX_AGENT_`. + +If you are upgrading from an older version, update your configuration accordingly. + +{{< /warning >}} + +{{}} +| CLI flag | Environment variable | Description | +|---------------------------------------------|--------------------------------------|-----------------------------------------------------------------------------| +| `--api-cert` | `NGINX_AGENT_API_CERT` | Specifies the certificate used by the Agent API. | +| `--api-host` | `NGINX_AGENT_API_HOST` | Sets the host used by the Agent API. Default: *127.0.0.1* | +| `--api-key` | `NGINX_AGENT_API_KEY` | Specifies the key used by the Agent API. | +| `--api-port` | `NGINX_AGENT_API_PORT` | Sets the port for exposing nginx-agent to HTTP traffic. | +| `--config-dirs` | `NGINX_AGENT_CONFIG_DIRS` | Defines directories NGINX Agent can read/write. Default: *"/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms"* | +| `--dataplane-report-interval` | `NGINX_AGENT_DATAPLANE_REPORT_INTERVAL` | Sets the interval for dataplane reporting. Default: *24h0m0s* | +| `--dataplane-status-poll-interval` | `NGINX_AGENT_DATAPLANE_STATUS_POLL_INTERVAL` | Sets the interval for polling dataplane status. Default: *30s* | +| `--display-name` | `NGINX_AGENT_DISPLAY_NAME` | Sets the instance's display name. | +| `--dynamic-config-path` | `NGINX_AGENT_DYNAMIC_CONFIG_PATH` | Specifies the path of the Agent dynamic config file. Default: *"/var/lib/nginx-agent/agent-dynamic.conf"* | +| `--features` | `NGINX_AGENT_FEATURES` | Specifies a comma-separated list of features enabled for the agent. Default: *[registration, nginx-config-async, nginx-ssl-config, nginx-counting, metrics, dataplane-status, process-watcher, file-watcher, activity-events, agent-api]* | +| `--ignore-directives` | | Specifies a comma-separated list of directives to ignore for sensitive info.| +| `--instance-group` | `NGINX_AGENT_INSTANCE_GROUP` | Sets the instance's group value. | +| `--log-level` | `NGINX_AGENT_LOG_LEVEL` | Sets the logging level (e.g., panic, fatal, error, info, debug, trace). Default: *info* | +| `--log-path` | `NGINX_AGENT_LOG_PATH` | Specifies the path to output log messages. | +| `--metrics-bulk-size` | `NGINX_AGENT_METRICS_BULK_SIZE` | Specifies the number of metrics reports collected before sending data. Default: *20* | +| `--metrics-collection-interval` | `NGINX_AGENT_METRICS_COLLECTION_INTERVAL` | Sets the interval for metrics collection. Default: *15s* | +| `--metrics-mode` | `NGINX_AGENT_METRICS_MODE` | Sets the metrics collection mode: streaming or aggregation. Default: *aggregated* | +| `--metrics-report-interval` | `NGINX_AGENT_METRICS_REPORT_INTERVAL` | Sets the interval for reporting collected metrics. Default: *1m0s* | +| `--nginx-config-reload-monitoring-period` | | Sets the duration to monitor error logs after an NGINX reload. Default: *10s* | +| `--nginx-exclude-logs` | `NGINX_AGENT_NGINX_EXCLUDE_LOGS` | Specifies paths of NGINX access logs to exclude from metrics collection. | +| `--nginx-socket` | `NGINX_AGENT_NGINX_SOCKET` | Specifies the location of the NGINX Plus counting Unix socket. Default: *unix:/var/run/nginx-agent/nginx.sock* | +| `--nginx-treat-warnings-as-errors` | `NGINX_AGENT_NGINX_TREAT_WARNINGS_AS_ERRORS` | Treats warnings as failures on configuration application. | +| `--queue-size` | `NGINX_AGENT_QUEUE_SIZE` | Specifies the size of the NGINX Agent internal queue. | +| `--server-command` | | Specifies the name of the command server sent in the TLS configuration. | +| `--server-grpcport` | `NGINX_AGENT_SERVER_GRPCPORT` | Sets the desired GRPC port for NGINX Agent traffic. | +| `--server-host` | `NGINX_AGENT_SERVER_HOST` | Specifies the IP address of the server host. | +| `--server-metrics` | | Specifies the name of the metrics server sent in the TLS configuration. | +| `--server-token` | `NGINX_AGENT_SERVER_TOKEN` | Sets the authentication token for accessing the commander and metrics services. Default: *e202f883-54c6-4702-be15-3ba6e507879a* | +| `--tags` | `NGINX_AGENT_TAGS` | Specifies a comma-separated list of tags for the instance or machine. | +| `--tls-ca` | `NGINX_AGENT_TLS_CA` | Specifies the path to the CA certificate file for TLS. | +| `--tls-cert` | `NGINX_AGENT_TLS_CERT` | Specifies the path to the certificate file for TLS. | +| `--tls-enable` | `NGINX_AGENT_TLS_ENABLE` | Enables TLS for secure communications. | +| `--tls-key` | `NGINX_AGENT_TLS_KEY` | Specifies the path to the certificate key file for TLS. | +| `--tls-skip-verify` | `NGINX_AGENT_TLS_SKIP_VERIFY` | Insecurely skips verification for gRPC TLS credentials. | +{{}} + +
+ +{{}} +Use the `--config-dirs` command-line option, or the `config_dirs` key in the `nginx-agent.conf` file, to identify the directories NGINX Agent can read from or write to. This setting also defines the location to which you can upload config files when using a control plane. + +NGINX Agent cannot write to directories outside the specified location when updating a config and cannot upload files to directories outside of the configured location. + +NGINX Agent follows NGINX configuration directives to file paths outside the designated directories and reads certificates' metadata. NGINX Agent uses the following directives: + +- [`ssl_certificate`](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) + +{{}} + +{{}} Use the `--dynamic-config-path` command-line option to set the location of the dynamic config file. This setting also requires you to move your dynamic config to the new path, or create a new dynamic config file at the specified location. + +Default location in Linux environments: `/var/lib/nginx-agent/agent-dynamic.conf` + +Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.conf` + +{{}} + +## Logs + +NGINX Agent uses formatted log files to collect metrics. Expanding log formats and instance counts will also increase the size of the NGINX Agent log files. + +We recommend adding a separate partition for `/var/log/nginx-agent`. + +{{< important >}} +Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services. +{{< /important >}} + +By default, NGINX Agent rotates logs daily using logrotate with the following configuration: + +
+ NGINX Agent Logrotate Configuration + +``` yaml +/var/log/nginx-agent/*.log +{ + # log files are rotated every day + daily + # log files are rotated if they grow bigger than 5M + size 5M + # truncate the original log file after creating a copy + copytruncate + # remove rotated logs older than 10 days + maxage 10 + # log files are rotated 10 times before being removed + rotate 10 + # old log files are compressed + compress + # if the log file is missing it will go on to the next one without issuing an error message + missingok + # do not rotate the log if it is empty + notifempty +} +``` +
+ +If you need to change the default configuration, update the file at `/etc/logrotate.d/nginx-agent`. + +For more details on logrotate configuration, see [Logrotate Configuration Options](https://linux.die.net/man/8/logrotate). + + +## Extensions + +An extension is noncritical code to the main functionality of NGINX Agent. They generally cover functionality outside of managing NGINX configuration and reporting metrics. + +To enable an extension, it must be added to the extensions list in the `/etc/nginx-agent/nginx-agent.conf`. + +This example enables the advanced metrics extension: + +```yaml +extensions: + - advanced-metrics +``` \ No newline at end of file diff --git a/site/content/configuration/configure-nginx-agent-group.md b/site/content/how-to/configure-agent-group.md similarity index 84% rename from site/content/configuration/configure-nginx-agent-group.md rename to site/content/how-to/configure-agent-group.md index 9aa87c9a0a..dbfd3c6dd7 100644 --- a/site/content/configuration/configure-nginx-agent-group.md +++ b/site/content/how-to/configure-agent-group.md @@ -1,13 +1,12 @@ --- -title: "Add NGINX Users to nginx-agent group" -draft: false -weight: 300 +title: "Add users to nginx-agent group" toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] +weight: 400 +docs: DOCS-000 --- +This page describes how the F5 NGINX Agent process interacts with the NGINX user on a system, and how to add users to the NGINX Agent group. + ## Overview During installation, NGINX Agent detects the NGINX user (typically `nginx`) for the master and worker processes and adds this user to a group called `nginx-agent`. @@ -16,8 +15,9 @@ If you change the NGINX username after installing the NGINX Agent, you'll need t A failure to update the `nginx-agent` group when the NGINX username changes may result in non-compliance errors for NGINX Plus. +--- -## NGINX Socket +## NGINX socket NGINX Agent creates a socket in the default location `/var/run/nginx-agent/nginx.sock`. You can customize this location by editing the `nginx-agent.conf` file and setting the path similar to the following example: @@ -29,57 +29,58 @@ nginx: The socket server starts when the NGINX socket configuration is enabled; the socket configuration is enabled by default. +--- -## Add NGINX Users to nginx-agent Group +## Add NGINX Users to nginx-agent group To manually add NGINX users to the `nginx-agent` group, take the following steps: 1. Verify the `nginx-agent` group exists: - ```bash + ```shell sudo getent group | grep nginx-agent ``` The output looks similar to the following example: - ```bash + ```shell nginx-agent:x:1001:root,nginx ``` If the group doesn't exist, create it by running the following command: - ```bash + ```shell sudo groupadd nginx-agent ``` 2. Verify the ownership of `/var/run/nginx-agent` directory: - ```bash + ```shell ls -l /var/run/nginx-agent ``` The output looks similar to the following: - ```bash + ```shell total 0 srwxrwxr-x 1 root nginx-agent 0 Jun 13 10:51 nginx.sockvv ``` If the group ownership is not `nginx-agent`, change the ownership by running the following command: - ```bash + ```shell sudo chown :nginx-agent /var/run/nginx-agent ``` 3. To add NGINX user(s) to the `nginx-agent` group, run the following command: - ```bash + ```shell sudo usermod -a -G nginx-agent ``` For example to add the `nginx` user, take the following step: - ```bash + ```shell sudo usermod -a -G nginx-agent nginx ``` diff --git a/site/content/configuration/connect-management-plane.md b/site/content/how-to/connect-management-plane.md similarity index 91% rename from site/content/configuration/connect-management-plane.md rename to site/content/how-to/connect-management-plane.md index c11c39c9a6..c0919d65eb 100644 --- a/site/content/configuration/connect-management-plane.md +++ b/site/content/how-to/connect-management-plane.md @@ -1,15 +1,13 @@ --- title: "Connect to management plane" -weight: 400 toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] +weight: 600 +docs: DOCS-000 --- ## Overview -To monitor and manage all your NGINX Agent instances from a central management plane server, you first need to connect your instances and the server. You can configure the connection by making the required changes to the NGINX Agent configuration file. +To monitor and manage all your F5 NGINX Agent instances from a central management plane server, you first need to connect your instances and the server. You can configure the connection by making the required changes to the NGINX Agent configuration file. There are three types of connections you can establish between the NGINX Agent and the management plane server: @@ -52,7 +50,7 @@ To establish a mTLS connection between the NGINX Agent and the management plane ``` 2. Restart the NGINX Agent service: - ```bash + ```shell sudo systemctl restart nginx-agent ``` @@ -86,7 +84,7 @@ To establish a TLS connection between the NGINX Agent and the management plane s 2. Restart the NGINX Agent service: - ```bash + ```shell sudo systemctl restart nginx-agent ``` @@ -111,6 +109,6 @@ To establish an insecure connection between the NGINX Agent and the management p 2. Restart the NGINX Agent service: - ```bash + ```shell sudo systemctl restart nginx-agent ``` diff --git a/site/content/how-to/enable-interfaces.md b/site/content/how-to/enable-interfaces.md new file mode 100644 index 0000000000..c73557165a --- /dev/null +++ b/site/content/how-to/enable-interfaces.md @@ -0,0 +1,73 @@ +--- +title: "Enable gRPC and REST interfaces" +toc: true +weight: 200 +docs: DOCS-000 +--- + +This document describes how to enable the gRPC and REST interfaces for F5 NGINX Agent. + +## Before you begin + +If it doesn't already exist, create the directory `/etc/nginx-agent/`and copy the `nginx-agent.conf` file into it from the project root directory. + +```shell +sudo mkdir /etc/nginx-agent +sudo cp /nginx-agent.conf /etc/nginx-agent/ +``` + +Create the `agent-dynamic.conf` file, which is required for NGINX Agent to run. + +In Linux environments: +```shell +sudo touch /var/lib/nginx-agent/agent-dynamic.conf +``` + +In FreeBSD environments: +```shell +sudo touch /var/db/nginx-agent/agent-dynamic.conf +``` + +--- + +## Enable the gRPC interface + +Add the the following settings to `/etc/nginx-agent/nginx-agent.conf`: + +```yaml +server: + host: 127.0.0.1 # mock control plane host + grpcPort: 54789 # mock control plane gRPC port + +# gRPC TLS options - DISABLING TLS IS NOT RECOMMENDED FOR PRODUCTION +tls: + enable: false + skip_verify: true +``` + +For more information, see [Agent Protocol Definitions and Documentation](https://github.com/nginx/agent/tree/main/docs/proto/README.md). + +--- + +## Enable the REST interface + +The NGINX Agent REST interface can be exposed by validating the following lines in the `/etc/nginx-agent/nginx-agent.conf` file are present: + +```yaml +api: + # Set API address to allow remote management + host: 127.0.0.1 + # Set this value to a secure port number to prevent information leaks + port: 8038 + # REST TLS parameters + cert: ".crt" + key: ".key" +``` + +--- + +## Start NGINX Agent + +To apply the new configuration, NGINX Agent must be started or restarted. + +You may want to view the [Start mock control plane interface]({{< relref "/contribute/start-mock-interface.md" >}}) topic to test NGINX Agent, or view the [Configuration overview]({{< relref "/how-to/configuration-overview.md" >}}) for more options. \ No newline at end of file diff --git a/site/content/configuration/encrypt-communication.md b/site/content/how-to/encrypt-communication.md similarity index 95% rename from site/content/configuration/encrypt-communication.md rename to site/content/how-to/encrypt-communication.md index 3ff8b8e3cc..00876ffc40 100644 --- a/site/content/configuration/encrypt-communication.md +++ b/site/content/how-to/encrypt-communication.md @@ -1,14 +1,13 @@ --- -title: Encrypt communication -tags: -- docs +title: "Encrypt communication" toc: true -weight: 200 +weight: 500 +docs: DOCS-000 --- ## Overview -Follow the steps in this guide to encrypt communication between NGINX Agent and Instance Manager with TLS. +Follow the steps in this guide to encrypt communication between F5 NGINX Agent and Instance Manager with TLS. ## Before You Begin @@ -40,7 +39,7 @@ The `cert-sni-name` value should match the SubjectAltName of the server certific To enable mTLS for the NGINX Agent from the command line, run the following command: -```bash +```shell nginx-agent --tls-cert "path-to-cert" --tls-key "path-to-key" --tls-ca "path-to-ca-cert" --tls-enable ``` @@ -48,7 +47,7 @@ nginx-agent --tls-cert "path-to-cert" --tls-key "path-to-key" --tls-ca "path-to- To enable mTLS for NGINX Agent using environment variables, run the following commands: -```bash +```shell NMS_TLS_CA="my-env-ca" NMS_TLS_KEY="my-env-key" NMS_TLS_CERT="my-env-cert" @@ -67,7 +66,7 @@ To enable server-side TLS you must have TLS enabled. See the following examples You can edit the `/etc/nginx-agent/nginx-agent.conf` file to enable server-side TLS. Make the following changes: -```bash +```shell tls: enable: true skip_verify: false @@ -77,7 +76,7 @@ tls: To enable server-side TLS from the command line, run the following command: -```bash +```shell nginx-agent --tls-enable ``` @@ -85,7 +84,7 @@ nginx-agent --tls-enable To enable server-side TLS using environment variables, run the following commands: -```bash +```shell NMS_TLS_ENABLE=true ``` @@ -99,7 +98,7 @@ NMS_TLS_ENABLE=true To enable server-side TLS with a self-signed certificate, you must have TLS enabled and set `skip_verify` to `true`, which disables hostname validation. Setting `skip_verify` can be done done only by updating the configuration file. See the following example: -```bash +```shell tls: enable: true skip_verify: true @@ -113,7 +112,7 @@ To enable insecure mode, you simply need to set `tls:enable` to `false`. Setting You can edit the `/etc/nginx-agent/nginx-agent.conf` file to enable insecure mode. Make the following changes: -```bash +```shell tls: enable: false ``` @@ -122,6 +121,6 @@ tls: To enable insecure mode using environment variables, run the following commands: -```bash +```shell NMS_TLS_ENABLE=false ``` diff --git a/site/content/how-to/export-metrics.md b/site/content/how-to/export-metrics.md new file mode 100644 index 0000000000..7bbd3a6871 --- /dev/null +++ b/site/content/how-to/export-metrics.md @@ -0,0 +1,45 @@ +--- +title: "Export metrics data" +weight: 300 +docs: DOCS-000 +--- + +This document describes how to export the metrics data from F5 NGINX Agent. + +[//]: # "These are Markdown comments to guide you through document structure." +[//]: # "Remove them as you go, as well as unnecessary sections for this use case." + +## Overview + +[//]: # "Write a description which outlines precisely what this page of instructions will accomplish." +[//]: # "This description, like all instructions, should be direct and imperative." +[//]: # "Avoid ambiguous promises such as 'enables functionality': state precisely what it does." + +--- + +## Before you begin + +[//]: # "List all of the prerequisites for completing this task." +[//]: # "This might be the first page for a reader, so include a link to installation." + +To begin this task, you will require the following: + +- A [working NGINX Agent instance]({{< ref "/install-upgrade/install.md" >}}). +- +- + +--- + +## Export metrics data + + + +--- + +## See also + +[//]: # "Examples of additional topics users might want to read include:" +[//]: # "Relevant reference information, configuration options and more complex use cases." + +- [OpenTelemetry metrics]({{< ref "/metrics.md" >}}) +- diff --git a/site/content/install-upgrade/_index.md b/site/content/install-upgrade/_index.md new file mode 100644 index 0000000000..db1eae8abf --- /dev/null +++ b/site/content/install-upgrade/_index.md @@ -0,0 +1,6 @@ +--- +title: "Install and upgrade" +weight: 400 +--- + +Learn how to install, upgrade, and uninstall NGINX Agent. \ No newline at end of file diff --git a/site/content/install-upgrade/container-environments/_index.md b/site/content/install-upgrade/container-environments/_index.md new file mode 100644 index 0000000000..bd7ec74ba0 --- /dev/null +++ b/site/content/install-upgrade/container-environments/_index.md @@ -0,0 +1,6 @@ +--- +title: "Container environments" +weight: 400 +--- + +Learn how to build and run NGINX Agent docker images. \ No newline at end of file diff --git a/site/content/installation-upgrade/container-environments/docker-images.md b/site/content/install-upgrade/container-environments/docker-images.md similarity index 90% rename from site/content/installation-upgrade/container-environments/docker-images.md rename to site/content/install-upgrade/container-environments/docker-images.md index 22f76645c3..28db5a6bd9 100644 --- a/site/content/installation-upgrade/container-environments/docker-images.md +++ b/site/content/install-upgrade/container-environments/docker-images.md @@ -1,22 +1,18 @@ --- title: "Build container images" -draft: false -weight: 100 toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] +weight: 100 +docs: DOCS-000 --- ## Overview -NGINX Agent is a companion daemon for NGINX Open Source or NGINX Plus instances and must run in the same container to work. The NGINX Agent GitHub repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that you can use to build custom container images that bundle NGINX Agent with NGINX or NGINX Plus. +F5 NGINX Agent is a companion daemon for NGINX Open Source or NGINX Plus instances and must run in the same container to work. The NGINX Agent GitHub repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that you can use to build custom container images that bundle NGINX Agent with NGINX or NGINX Plus. If you want to use NGINX Agent with NGINX Plus, you need to purchase an NGINX Plus license. Contact your F5 Sales representative for assistance. See the requirements and supported operating systems in the [NGINX Agent Technical Specifications]({{< relref "technical-specifications.md" >}}) topic. - ## Set up your environment ### Install a container engine @@ -158,47 +154,36 @@ $ docker build -t nginx-agent . \ Here is an example of how to run the NGINX Agent container using Docker: -```console +```shell docker run --name nginx-agent -d nginx-agent ``` -{{}}To learn more about the configuration options, refer to the NGINX Agent [Configuration Overview]({{< relref "/configuration/configuration-overview" >}}).{{}} +{{< note >}} To learn more about the configuration options, refer to the [Configuration overview]({{< relref "/how-to/configuration-overview" >}}) topic. {{}} + +--- ### Enable the gRPC interface -To connect your NGINX Agent container to your NGINX One or NGINX Instance Manager instance, you must enable the gRPC interface. To do this, you must edit the NGINX Agent configuration file, *nginx-agent.conf*. For example: +To connect your NGINX Agent container to your NGINX One or NGINX Instance Manager instance, you must enable the gRPC interface. -```yaml -erver: - host: 127.0.0.1 # mock control plane host - grpcPort: 54789 # mock control plane gRPC port +The configuration required is explained in the [Enable the gRPC interface]({{< relref "/how-to/enable-interfaces.md#enable-the-grpc-interface" >}}) -# gRPC TLS options - DISABLING TLS IS NOT RECOMMENDED FOR PRODUCTION -tls: - enable: false - skip_verify: true -``` +--- ### Enable the REST interface -If your control plane requires REST API, you can expose NGINX Agent's REST API by editing the NGINX Agent configuration file, *nginx-agent.conf*. For example: - -```yaml -api: - host: 0.0.0.0 - port: 8038 -``` +If your control plane requires a REST API, you can [Enable the REST interface]({{< relref "/how-to/enable-interfaces.md#enable-the-rest-interfacee" >}}) for NGINX Agent. Once you have updated the *nginx-agent.conf* file, you can run the container with the updated **nginx-agent.conf** mounted and the port **8038** exposed with the following command: -```console +```shell docker run --name nginx-agent -d \ --mount type=bind,source="$(pwd)"/nginx-agent.conf,target=/etc/nginx-agent/nginx-agent.conf,readonly \ -p 127.0.0.1:8038:8038/tcp \ nginx-agent ``` -
+--- ## Build the NGINX Agent images for specific OS targets diff --git a/site/content/installation-upgrade/container-environments/docker-support.md b/site/content/install-upgrade/container-environments/docker-support.md similarity index 84% rename from site/content/installation-upgrade/container-environments/docker-support.md rename to site/content/install-upgrade/container-environments/docker-support.md index be0605ab55..f6e41ad6fd 100644 --- a/site/content/installation-upgrade/container-environments/docker-support.md +++ b/site/content/install-upgrade/container-environments/docker-support.md @@ -1,17 +1,13 @@ --- -title: Container support and troubleshooting -categories: -- installation -draft: false -tags: -- docs +title: "Container support and troubleshooting" toc: true weight: 200 +docs: DOCS-000 --- ## Overview -The NGINX Agent repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that can be used to [build custom container images]({{< relref "installation-upgrade/container-environments/docker-images.md" >}}). Images are created with an NGINX Open Source or NGINX Plus instance and are available for various operating systems. +The F5 NGINX Agent repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that can be used to [build custom container images]({{< relref "/install-upgrade/container-environments/docker-images.md" >}}). Images are created with an NGINX Open Source or NGINX Plus instance and are available for various operating systems. See the [Technical Specifications]({{< relref "/technical-specifications.md#container-support" >}}) for a list of supported operationg systems. @@ -58,7 +54,7 @@ If no memory limit is set when starting the Docker container, then the memory li If a warning message similar to the following example is seen in the NGINX Agent logs, the swap memory limit for the Docker container is greater than the swap memory for the Docker host system: -```bash +```shell Swap memory limit specified for the container, ... is greater than the host system swap memory ... ``` @@ -66,7 +62,7 @@ The `system.swap.total` metric for the container matches the total swap memory f If a warning message similar to the following example is seen in the NGINX Agent logs, the Docker host system does not have cgroup swap limit capabilities enabled. To enable these capabilities, follow the steps below. -```bash +```shell Unable to collect Swap metrics because the file ... was not found ``` @@ -74,7 +70,7 @@ Unable to collect Swap metrics because the file ... was not found Run the following command to see if the cgroup swap limit capabilities are enabled: -```bash +```shell $ docker info | grep swap WARNING: No swap limit support ``` diff --git a/site/content/install-upgrade/install.md b/site/content/install-upgrade/install.md new file mode 100644 index 0000000000..95f6514684 --- /dev/null +++ b/site/content/install-upgrade/install.md @@ -0,0 +1,784 @@ +--- +title: Install NGINX Agent +toc: true +weight: 100 +docs: DOCS-000 +--- + +This document describes the three main ways to install F5 NGINX agent: + +- Using the NGINX Open Source repository +- Using the NGINX Plus repository +- Using the GitHub package files + +## Before you begin + +There are a few prerequisites shared between all installation methods: + +- A [supported operating system and architecture](../technical-specifications/#supported-distributions) +- `root` privilege + +## NGINX Open Source repository + +Before you install NGINX Agent, you must install and run NGINX. + +If you don't have it installed already, read the [Installing NGINX Open Source +](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/) topic. + + +### Configure NGINX OSS Repository for installing NGINX Agent + +Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository. + +- [Install NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#install-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) +- [Install NGINX Agent on Ubuntu](#install-nginx-agent-on-ubuntu) +- [Install NGINX Agent on Debian](#install-nginx-agent-on-debian) +- [Install NGINX Agent on SLES](#install-nginx-agent-on-sles) +- [Install NGINX Agent on Alpine Linux](#install-nginx-agent-on-alpine-linux) +- [Install NGINX Agent on Amazon Linux](#install-nginx-agent-on-amazon-linux) +- [Install NGINX Agent on FreeBSD](#install-nginx-agent-on-freebsd) + +#### Install NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux + +1. Install the prerequisites: + + ```shell + sudo yum install yum-utils + ``` + +1. To set up the yum repository, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: + + ``` + [nginx-agent] + name=nginx agent repo + baseurl=http://packages.nginx.org/nginx-agent/centos/$releasever/$basearch/ + gpgcheck=1 + enabled=1 + gpgkey=https://nginx.org/keys/nginx_signing.key + module_hotfixes=true + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo yum install nginx-agent + ``` + + When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Install NGINX Agent on Ubuntu + +1. Install the prerequisites: + + ```shell + sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring + ``` + +1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: + + ```shell + curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ + | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null + ``` + +1. Verify that the downloaded file contains the proper key: + + ```shell + gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg + ``` + + The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + + ``` + pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + ``` + + {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} + +1. Add the nginx agent repository: + + ```shell + echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ + http://packages.nginx.org/nginx-agent/ubuntu/ `lsb_release -cs` agent" \ + | sudo tee /etc/apt/sources.list.d/nginx-agent.list + ``` + +1. To install `nginx-agent`, run the following commands: + + ```shell + sudo apt update + sudo apt install nginx-agent + ``` + +#### Install NGINX Agent on Debian + +1. Install the prerequisites: + + ```shell + sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring + ``` + +1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: + + ```shell + curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ + | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null + ``` + +1. Verify that the downloaded file contains the proper key: + + ```shell + gpg --dry-run --quiet --no-keyring \ + --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg + ``` + + The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + + ``` + pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + ``` + + {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} + +1. Add the `nginx-agent` repository: + + ```shell + echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ + http://packages.nginx.org/nginx-agent/debian/ `lsb_release -cs` agent" \ | sudo tee /etc/apt/sources.list.d/nginx-agent.list + ``` + +1. To install `nginx-agent`, run the following commands: + + ```shell + sudo apt update + sudo apt install nginx-agent + ``` + +#### Install NGINX Agent on SLES + +1. Install the prerequisites: + + ```shell + sudo zypper install curl ca-certificates gpg2 gawk + ``` + +1. To set up the zypper repository for `nginx-agent` packages, run the following command: + + ```shell + sudo zypper addrepo --gpgcheck --refresh --check \ + 'http://packages.nginx.org/nginx-agent/sles/$releasever_major' nginx-agent + ``` + +1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key: + + ```shell + curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key + ``` + +1. Verify that the downloaded file contains the proper key: + + ```shell + gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key + ``` + +1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: + + ``` + pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] + 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 + uid nginx signing key + ``` + +1. Finally, import the key to the rpm database: + + ```shell + sudo rpmkeys --import /tmp/nginx_signing.key + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo zypper install nginx-agent + ``` + +#### Install NGINX Agent on Alpine Linux + +1. Install the prerequisites: + + ```shell + sudo apk add openssl curl ca-certificates + ``` + +1. To set up the apk repository for `nginx-agent` packages, run the following command: + + ```shell + printf "%s%s%s\n" \ + "http://packages.nginx.org/nginx-agent/alpine/v" \ + `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \ + "/main" \ + | sudo tee -a /etc/apk/repositories + ``` + +1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key: + + ```shell + curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub + ``` + +1. Verify that downloaded file contains the proper key: + + ```shell + openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout + ``` + + The output should contain the following modulus: + + ``` + Public-Key: (2048 bit) + Modulus: + 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58: + 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70: + 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1: + f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab: + 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f: + 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64: + 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d: + 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3: + 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c: + 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34: + 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f: + 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17: + 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99: + 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67: + c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e: + ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4: + 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f: + ab:6d + Exponent: 65537 (0x10001) + ``` + +1. Finally, move the key to apk trusted keys storage: + + ```shell + sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/ + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo apk add nginx-agent + ``` + +#### Install NGINX Agent on Amazon Linux + +1. Install the prerequisites: + + ```shell + sudo yum install yum-utils procps + ``` + +1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: + ``` + [nginx-agent] + name=nginx agent repo + baseurl=http://packages.nginx.org/nginx-agent/amzn2/$releasever/$basearch/ + gpgcheck=1 + enabled=1 + gpgkey=https://nginx.org/keys/nginx_signing.key + module_hotfixes=true + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo yum install nginx-agent + ``` + +1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Install NGINX Agent on FreeBSD + +1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content: + + ``` + nginx-agent: { + URL: pkg+http://packages.nginx.org/nginx-agent/freebsd/${ABI}/latest + ENABLED: true + MIRROR_TYPE: SRV + } + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo pkg install nginx-agent + ``` + +## NGINX Plus repository + +Before you install NGINX Agent, you must install and run NGINX Plus. + +If you don’t have it installed already, read the [Installing NGINX Plus +](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/) topic. + +You will also need the following: + +- Your credentials to the MyF5 Customer Portal, provided by email from F5, Inc. +- An NGINX Plus subscription (Full or trial) +- Your NGINX Plus certificate and public key (`nginx-repo.crt` and `nginx-repo.key` files), provided by email from F5, Inc. + +### Configure NGINX Plus Repository for installing NGINX Agent + +Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository. + +- [Install NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#install-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) +- [Install NGINX Agent on Ubuntu](#install-nginx-agent-on-ubuntu) +- [Install NGINX Agent on Debian](#install-nginx-agent-on-debian) +- [Install NGINX Agent on SLES](#install-nginx-agent-on-sles) +- [Install NGINX Agent on Alpine Linux](#install-nginx-agent-on-alpine-linux) +- [Install NGINX Agent on Amazon Linux](#install-nginx-agent-on-amazon-linux) +- [Install NGINX Agent on FreeBSD](#install-nginx-agent-on-freebsd) + +#### Install NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisites: + + ```shell + sudo yum install yum-utils procps + ``` + +1. Set up the yum repository by creating the file `nginx-agent.repo` in `/etc/yum.repos.d`, for example using `vi`: + + ```shell + sudo vi /etc/yum.repos.d/nginx-agent.repo + ``` + +1. Add the following lines to `nginx-agent.repo`: + + ``` + [nginx-agent] + name=nginx agent repo + baseurl=https://pkgs.nginx.com/nginx-agent/centos/$releasever/$basearch/ + sslclientcert=/etc/ssl/nginx/nginx-repo.crt + sslclientkey=/etc/ssl/nginx/nginx-repo.key + gpgcheck=0 + enabled=1 + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo yum install nginx-agent + ``` + + When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Install NGINX Agent on Ubuntu + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisites: + + ```shell + sudo apt-get install apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring + ``` + +1. Download and add [NGINX signing key](https://cs.nginx.com/static/keys/nginx_signing.key): + + ```shell + wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null + ``` + +1. Create `apt` configuration `/etc/apt/apt.conf.d/90pkgs-nginx`: + + ``` + Acquire::https::pkgs.nginx.com::Verify-Peer "true"; + Acquire::https::pkgs.nginx.com::Verify-Host "true"; + Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt"; + Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key"; + ``` + +1. Add the `nginx-agent` repository: + + ```shell + echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/nginx-agent/ubuntu/ `lsb_release -cs` agent" \ + | sudo tee /etc/apt/sources.list.d/nginx-agent.list + ``` + +1. To install `nginx-agent`, run the following commands: + + ```shell + sudo apt update + sudo apt install nginx-agent + ``` + +#### Install NGINX Agent on Debian + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisites: + + ```shell + sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring + ``` + +1. Add the `nginx-agent` repository: + + ```shell + echo "deb https://pkgs.nginx.com/nginx-agent/debian/ `lsb_release -cs` agent" \ + | sudo tee /etc/apt/sources.list.d/nginx-agent.list + ``` + +1. Create apt configuration `/etc/apt/apt.conf.d/90pkgs-nginx`: + + ``` + Acquire::https::pkgs.nginx.com::Verify-Peer "true"; + Acquire::https::pkgs.nginx.com::Verify-Host "true"; + Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt"; + Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key"; + ``` + +1. To install `nginx-agent`, run the following commands: + + ```shell + sudo apt update + sudo apt install nginx-agent + ``` + +#### Install NGINX Agent on SLES + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Create a file bundle of the certificate and key: + + ```shell + cat /etc/ssl/nginx/nginx-repo.crt /etc/ssl/nginx/nginx-repo.key > /etc/ssl/nginx/nginx-repo-bundle.crt + ``` + +1. Install the prerequisites: + + ```shell + sudo zypper install curl ca-certificates gpg2 gawk + ``` + +1. To set up the zypper repository for `nginx-agent` packages, run the following command: + + ```shell + sudo zypper addrepo --refresh --check \ + 'https://pkgs.nginx.com/nginx-agent/sles/$releasever_major?ssl_clientcert=/etc/ssl/nginx/nginx-repo-bundle.crt&ssl_verify=peer' nginx-agent + ``` + +1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key: + + ```shell + curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key + ``` + +1. Verify that the downloaded file contains the proper key: + + ```shell + gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key + ``` + +1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: + + ``` + pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] + 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 + uid nginx signing key + ``` + +1. Finally, import the key to the rpm database: + + ```shell + sudo rpmkeys --import /tmp/nginx_signing.key + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo zypper install nginx-agent + ``` + +#### Install NGINX Agent on Alpine Linux + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/apk/` directory: + + ```shell + sudo cp nginx-repo.key /etc/apk/cert.key + sudo cp nginx-repo.crt /etc/apk/cert.pem + ``` + +1. Install the prerequisites: + + ```shell + sudo apk add openssl curl ca-certificates + ``` + +1. To set up the apk repository for `nginx-agent` packages, run the following command: + + ```shell + printf "%s%s%s\n" \ + "https://pkgs.nginx.com/nginx-agent/alpine/v" \ + `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \ + "/main" \ + | sudo tee -a /etc/apk/repositories + ``` + +1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key: + + ```shell + curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub + ``` + +1. Verify that downloaded file contains the proper key: + + ```shell + openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout + ``` + + The output should contain the following modulus: + + ``` + Public-Key: (2048 bit) + Modulus: + 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58: + 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70: + 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1: + f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab: + 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f: + 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64: + 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d: + 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3: + 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c: + 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34: + 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f: + 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17: + 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99: + 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67: + c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e: + ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4: + 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f: + ab:6d + Exponent: 65537 (0x10001) + ``` + +1. Finally, move the key to apk trusted keys storage: + + ```shell + sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/ + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo apk add nginx-agent + ``` + +#### Install NGINX Agent on Amazon Linux + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the `nginx-repo.crt` and `nginx-repo.key` files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisites: + + ```shell + sudo yum install yum-utils procps ca-certificates + ``` + +1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: + + ``` + [nginx-agent] + name=nginx-agent repo + baseurl=https://pkgs.nginx.com/nginx-agent/amzn2/$releasever/$basearch + sslclientcert=/etc/ssl/nginx/nginx-repo.crt + sslclientkey=/etc/ssl/nginx/nginx-repo.key + gpgcheck=0 + enabled=1 + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo yum install nginx-agent + ``` + +1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Install NGINX Agent on FreeBSD + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisite `ca_root_nss` package: + + ```shell + sudo pkg install ca_root_nss + ``` + +1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content: + + ``` + nginx-agent: { + URL: pkg+https://pkgs.nginx.com/nginx-agent/freebsd/${ABI}/latest + ENABLED: yes + MIRROR_TYPE: SRV + } + ``` + +1. Add the following lines to the `/usr/local/etc/pkg.conf` file: + + ``` + PKG_ENV: { SSL_NO_VERIFY_PEER: "1", + SSL_CLIENT_CERT_FILE: "/etc/ssl/nginx/nginx-repo.crt", + SSL_CLIENT_KEY_FILE: "/etc/ssl/nginx/nginx-repo.key" } + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo pkg install nginx-agent + ``` + +## GitHub package files + +To install NGINX Agent on your system, go to the [GitHub releases page](https://github.com/nginx/agent/releases) and download the latest package supported by your operating system distribution and CPU architecture. + +Use your system's package manager to install the package. Some examples: + +- Debian, Ubuntu, and other distributions using the `dpkg` package manager. + + ```shell + sudo dpkg -i nginx-agent-.deb + ``` + +- RHEL, CentOS RHEL, Amazon Linux, Oracle Linux, and other distributions using the `yum` package manager + + ```shell + sudo yum localinstall nginx-agent-.rpm + ``` + +- RHEL and other distributions using the `rpm` package manager + + ```shell + sudo rpm -i nginx-agent-.rpm + ``` + +- Alpine Linux + + ```shell + sudo apk add nginx-agent-.apk + ``` + +- FreeBSD + + ```shell + sudo pkg add nginx-agent-.pkg + ``` + +## systemd environments + +To start NGINX Agent on `systemd` systems, run the following command: + +```shell +sudo systemctl start nginx-agent +``` + +To enable NGINX Agent to start on boot, run the following command: + +```shell +sudo systemctl enable nginx-agent +``` + +## Verify that NGINX Agent is running + +Once you have installed NGINX Agent, you can verify that it is running with the following command: + +```shell +sudo nginx-agent -v +``` + +## Enable interfaces + +Once NGINX Agent is successfully running, you can enable the required interfaces, which is described in the [Enable gRPC and REST interfaces]({{< relref "/how-to/enable-interfaces.md" >}}) topic. + +You may also be interested in the [Start mock control plane interface]({{< relref "/contribute/start-mock-interface.md" >}}) topic for development work. \ No newline at end of file diff --git a/site/content/install-upgrade/migrate-v3.md b/site/content/install-upgrade/migrate-v3.md new file mode 100644 index 0000000000..fe9a0533f3 --- /dev/null +++ b/site/content/install-upgrade/migrate-v3.md @@ -0,0 +1,44 @@ +--- +title: Migrate from NGINX Agent v2 to v3 +weight: 500 +docs: DOCS-000 +--- + +This topic describes how to migrate from F5 NGINX Agent v2 to NGINX Agent v3. + +[//]: # "These are Markdown comments to guide you through document structure." +[//]: # "Remove them as you go, as well as unnecessary sections for this use case." + +## Overview + +[//]: # "Write a description which outlines precisely what this page of instructions will accomplish." +[//]: # "This description, like all instructions, should be direct and imperative." +[//]: # "Avoid ambiguous promises such as 'enables functionality': state precisely what it does." + +--- + +## Before you begin + +[//]: # "List all of the prerequisites for completing this task." +[//]: # "This might be the first page for a reader, so include a link to installation." + +To begin this task, you will require the following: + +- A [working NGINX Agent instance]({{< ref "/install-upgrade/install.md" >}}). +- +- + +--- + +## Migrate from NGINX Agent v2 to v3 + + +--- + +## See also + +[//]: # "Examples of additional topics users might want to read include:" +[//]: # "Relevant reference information, configuration options and more complex use cases." + +- +- diff --git a/site/content/install-upgrade/uninstall.md b/site/content/install-upgrade/uninstall.md new file mode 100644 index 0000000000..7fe869d585 --- /dev/null +++ b/site/content/install-upgrade/uninstall.md @@ -0,0 +1,145 @@ +--- +title: "Uninstall NGINX Agent" +toc: true +weight: 300 +docs: DOCS-000 +--- + +## Overview + +Learn how to uninstall F5 NGINX Agent from your system. + +## Before you begin + +### Prerequisites + +- NGINX Agent installed [NGINX Agent installed](../installation-oss) +- The user following these steps will need `root` privilege + +## Uninstall NGINX Agent +Complete the following steps on each host where you’ve installed NGINX Agent + + +- [Uninstall NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#uninstall-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) +- [Uninstall NGINX Agent on Ubuntu](#uninstall-nginx-agent-on-ubuntu) +- [Uninstall NGINX Agent on Debian](#uninstall-nginx-agent-on-debian) +- [Uninstall NGINX Agent on SLES](#uninstall-nginx-agent-on-sles) +- [Uninstall NGINX Agent on Alpine Linux](#uninstall-nginx-agent-on-alpine-linux) +- [Uninstall NGINX Agent on Amazon Linux](#uninstall-nginx-agent-on-amazon-linux) +- [Uninstall NGINX Agent on FreeBSD](#uninstall-nginx-agent-on-freebsd) + +### Uninstall NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux + +Complete the following steps on each host where you've installed NGINX Agent: + +1. Stop NGINX Agent: + + ```shell + sudo systemctl stop nginx-agent + ``` + +1. To uninstall NGINX Agent, run the following command: + + ```shell + sudo yum remove nginx-agent + ``` + +### Uninstall NGINX Agent on Ubuntu + +Complete the following steps on each host where you've installed NGINX Agent: + +1. Stop NGINX Agent: + + ```shell + sudo systemctl stop nginx-agent + ``` + +1. To uninstall NGINX Agent, run the following command: + + ```shell + sudo apt-get remove nginx-agent + ``` + + {{< note >}} The `apt-get remove ` command will remove the package from your system, while keeping the associated configuration files for possible future use. If you want to completely remove the package and all of its configuration files, you should use `apt-get purge `. {{< /note >}} + +### Uninstall NGINX Agent on Debian + +Complete the following steps on each host where you've installed NGINX Agent: + +1. Stop NGINX Agent: + + ```shell + sudo systemctl stop nginx-agent + ``` + +1. To uninstall NGINX Agent, run the following command: + + ```shell + sudo apt-get remove nginx-agent + ``` + + {{< note >}} The `apt-get remove ` command will remove the package from your system, while keeping the associated configuration files for possible future use. If you want to completely remove the package and all of its configuration files, you should use `apt-get purge `. {{< /note >}} + +### Uninstall NGINX Agent on SLES + +Complete the following steps on each host where you've installed NGINX Agent: + +1. Stop NGINX agent: + + ```shell + sudo systemctl stop nginx-agent + ``` + +1. To uninstall NGINX agent, run the following command: + + ```shell + sudo zypper remove nginx-agent + ``` + +### Uninstall NGINX Agent on Alpine Linux + +Complete the following steps on each host where you've installed NGINX agent: + +1. Stop NGINX agent: + + ```shell + sudo rc-service nginx-agent stop + ``` + +1. To uninstall NGINX agent, run the following command: + + ```shell + sudo apk del nginx-agent + ``` + +### Uninstall NGINX Agent on Amazon Linux + +Complete the following steps on each host where you've installed NGINX agent: + +1. Stop NGINX agent: + + ```shell + sudo systemctl stop nginx-agent + ``` + +1. To uninstall NGINX agent, run the following command: + + ```shell + sudo yum remove nginx-agent + ``` + +### Uninstall NGINX Agent on FreeBSD + +Complete the following steps on each host where you've installed NGINX agent: + +1. Stop NGINX agent: + + ```shell + sudo service nginx-agent stop + ``` + +1. To uninstall NGINX agent, run the following command: + + ```shell + sudo pkg delete nginx-agent + ``` diff --git a/site/content/installation-upgrade/upgrade.md b/site/content/install-upgrade/upgrade.md similarity index 92% rename from site/content/installation-upgrade/upgrade.md rename to site/content/install-upgrade/upgrade.md index 4e0f445398..55898a2bb7 100644 --- a/site/content/installation-upgrade/upgrade.md +++ b/site/content/install-upgrade/upgrade.md @@ -1,16 +1,13 @@ --- -title: "Upgrade NGINX Agent package" -draft: false -weight: 600 +title: "Upgrade NGINX Agent" toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] +weight: 200 +docs: DOCS-000 --- ## Overview -Learn how to upgrade NGINX Agent. +Learn how to upgrade F5 NGINX Agent. ## Upgrade NGINX Agent from version v2.31.0 or greater @@ -41,8 +38,6 @@ To upgrade NGINX Agent, follow these steps: sudo apt-get install -y --only-upgrade nginx-agent -o Dpkg::Options::="--force-confold" ``` - - ## Upgrade NGINX Agent from a version less than v2.31.0 To upgrade NGINX Agent, take the following steps: diff --git a/site/content/installation-upgrade/_index.md b/site/content/installation-upgrade/_index.md deleted file mode 100644 index 4c3d498997..0000000000 --- a/site/content/installation-upgrade/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Installation and upgrade" -description: "Learn how to install, upgrade, and uninstall NGINX Agent." -menu: docs -weight: 300 ---- \ No newline at end of file diff --git a/site/content/installation-upgrade/container-environments/_index.md b/site/content/installation-upgrade/container-environments/_index.md deleted file mode 100644 index e2de9f52c2..0000000000 --- a/site/content/installation-upgrade/container-environments/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Container Environments" -description: "Learn how to build and run NGINX Agent docker images." -menu: docs -weight: 800 ---- \ No newline at end of file diff --git a/site/content/installation-upgrade/installation-github.md b/site/content/installation-upgrade/installation-github.md deleted file mode 100644 index 20c3568f2b..0000000000 --- a/site/content/installation-upgrade/installation-github.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Installation from GitHub release" -draft: false -weight: 200 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -Learn how to install NGINX Agent from a GitHub Release. - -## Install NGINX - -NGINX Agent interfaces directly with an NGINX server process installed on the same system. If you don't have it already, follow these steps to install [NGINX Open Source](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/) or [NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/). Once installed, ensure the NGINX instance is running. - -## Install NGINX Agent from Package Files - -To install NGINX Agent on your system, go to [GitHub Releases](https://github.com/nginx/agent/releases) and download the latest package supported by your OS distribution and CPU architecture. - -Use your system's package manager to install the package. Some examples: - -- Debian, Ubuntu, and other distributions using the `dpkg` package manager. - - ```shell - sudo dpkg -i nginx-agent-.deb - ``` - -- RHEL, CentOS RHEL, Amazon Linux, Oracle Linux, and other distributions using the `yum` package manager - - ```shell - sudo yum localinstall nginx-agent-.rpm - ``` - -- RHEL and other distributions using the `rpm` package manager - - ```shell - sudo rpm -i nginx-agent-.rpm - ``` - -- Alpine Linux - - ```shell - sudo apk add nginx-agent-.apk - ``` - -- FreeBSD - - ```shell - sudo pkg add nginx-agent-.pkg - ``` diff --git a/site/content/installation-upgrade/installation-oss.md b/site/content/installation-upgrade/installation-oss.md deleted file mode 100644 index d3c42ef31f..0000000000 --- a/site/content/installation-upgrade/installation-oss.md +++ /dev/null @@ -1,349 +0,0 @@ ---- -title: "Installation from NGINX repository" -draft: false -weight: 300 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -Learn how to install NGINX Agent from the NGINX Open Source repository. - -## Prerequisites - -- NGINX installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/) -- A [supported operating system and architecture](../technical-specifications/#supported-distributions) -- `root` privilege - -## Configure NGINX OSS Repository for installing NGINX Agent - -Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository. - -- [Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#installing-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) -- [Installing NGINX Agent on Ubuntu](#installing-nginx-agent-on-ubuntu) -- [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian) -- [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles) -- [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux) -- [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux) -- [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd) - -### Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux - -1. Install the prerequisites: - - ```shell - sudo yum install yum-utils - ``` - -1. To set up the yum repository, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: - - ``` - [nginx-agent] - name=nginx agent repo - baseurl=http://packages.nginx.org/nginx-agent/centos/$releasever/$basearch/ - gpgcheck=1 - enabled=1 - gpgkey=https://nginx.org/keys/nginx_signing.key - module_hotfixes=true - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo yum install nginx-agent - ``` - - When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. - -### Installing NGINX Agent on Ubuntu - -1. Install the prerequisites: - - ```shell - sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring - ``` - -1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: - - ```shell - curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ - | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null - ``` - -1. Verify that the downloaded file contains the proper key: - - ```shell - gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg - ``` - - The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: - - ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 - uid nginx signing key - ``` - - {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} - -1. Add the nginx agent repository: - - ```shell - echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ - http://packages.nginx.org/nginx-agent/ubuntu/ `lsb_release -cs` agent" \ - | sudo tee /etc/apt/sources.list.d/nginx-agent.list - ``` - -1. To install `nginx-agent`, run the following commands: - - ```shell - sudo apt update - sudo apt install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - - -### Installing NGINX Agent on Debian - -1. Install the prerequisites: - - ```shell - sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring - ``` - -1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: - - ```shell - curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ - | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null - ``` - -1. Verify that the downloaded file contains the proper key: - - ```shell - gpg --dry-run --quiet --no-keyring \ - --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg - ``` - - The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: - - ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 - uid nginx signing key - ``` - - {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} - -1. Add the `nginx-agent` repository: - - ```shell - echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ - http://packages.nginx.org/nginx-agent/debian/ `lsb_release -cs` agent" \ | sudo tee /etc/apt/sources.list.d/nginx-agent.list - ``` - -1. To install `nginx-agent`, run the following commands: - - ```shell - sudo apt update - sudo apt install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - - -### Installing NGINX Agent on SLES - -1. Install the prerequisites: - - ```shell - sudo zypper install curl ca-certificates gpg2 gawk - ``` - -1. To set up the zypper repository for `nginx-agent` packages, run the following command: - - ```shell - sudo zypper addrepo --gpgcheck --refresh --check \ - 'http://packages.nginx.org/nginx-agent/sles/$releasever_major' nginx-agent - ``` - -1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key: - - ```shell - curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key - ``` - -1. Verify that the downloaded file contains the proper key: - - ```shell - gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key - ``` - -1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: - - ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 - uid nginx signing key - ``` - -1. Finally, import the key to the rpm database: - - ```shell - sudo rpmkeys --import /tmp/nginx_signing.key - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo zypper install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on Alpine Linux - -1. Install the prerequisites: - - ```shell - sudo apk add openssl curl ca-certificates - ``` - -1. To set up the apk repository for `nginx-agent` packages, run the following command: - - ```shell - printf "%s%s%s\n" \ - "http://packages.nginx.org/nginx-agent/alpine/v" \ - `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \ - "/main" \ - | sudo tee -a /etc/apk/repositories - ``` - -1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key: - - ```shell - curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub - ``` - -1. Verify that downloaded file contains the proper key: - - ```shell - openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout - ``` - - The output should contain the following modulus: - - ``` - Public-Key: (2048 bit) - Modulus: - 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58: - 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70: - 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1: - f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab: - 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f: - 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64: - 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d: - 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3: - 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c: - 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34: - 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f: - 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17: - 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99: - 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67: - c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e: - ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4: - 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f: - ab:6d - Exponent: 65537 (0x10001) - ``` - -1. Finally, move the key to apk trusted keys storage: - - ```shell - sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/ - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo apk add nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on Amazon Linux - -1. Install the prerequisites: - - ```shell - sudo yum install yum-utils procps - ``` - -1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: - ``` - [nginx-agent] - name=nginx agent repo - baseurl=http://packages.nginx.org/nginx-agent/amzn2/$releasever/$basearch/ - gpgcheck=1 - enabled=1 - gpgkey=https://nginx.org/keys/nginx_signing.key - module_hotfixes=true - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo yum install nginx-agent - ``` - -1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on FreeBSD - -1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content: - - ``` - nginx-agent: { - URL: pkg+http://packages.nginx.org/nginx-agent/freebsd/${ABI}/latest - ENABLED: true - MIRROR_TYPE: SRV - } - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo pkg install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` diff --git a/site/content/installation-upgrade/installation-plus.md b/site/content/installation-upgrade/installation-plus.md deleted file mode 100644 index 643d021697..0000000000 --- a/site/content/installation-upgrade/installation-plus.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -title: "Installation from NGINX Plus repository" -draft: false -weight: 400 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -Learn how to install NGINX Agent from NGINX Plus repository - -## Prerequisites - -- An NGINX Plus subscription (purchased or trial) -- NGINX Plus installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/) -- A [supported operating system and architecture](../technical-specifications/#supported-distributions) -- `root` privilege -- Your credentials to the MyF5 Customer Portal, provided by email from F5, Inc. -- Your NGINX Plus certificate and public key (`nginx-repo.crt` and `nginx-repo.key` files), provided by email from F5, Inc. - -## Configure NGINX Plus Repository for installing NGINX Agent - -Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository. - -- [Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#installing-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) -- [Installing NGINX Agent on Ubuntu](#installing-nginx-agent-on-ubuntu) -- [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian) -- [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles) -- [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux) -- [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux) -- [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd) - -### Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Install the prerequisites: - - ```shell - sudo yum install yum-utils procps - ``` - -1. Set up the yum repository by creating the file `nginx-agent.repo` in `/etc/yum.repos.d`, for example using `vi`: - - ```shell - sudo vi /etc/yum.repos.d/nginx-agent.repo - ``` - -1. Add the following lines to `nginx-agent.repo`: - - ``` - [nginx-agent] - name=nginx agent repo - baseurl=https://pkgs.nginx.com/nginx-agent/centos/$releasever/$basearch/ - sslclientcert=/etc/ssl/nginx/nginx-repo.crt - sslclientkey=/etc/ssl/nginx/nginx-repo.key - gpgcheck=0 - enabled=1 - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo yum install nginx-agent - ``` - - When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on Ubuntu - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Install the prerequisites: - - ```shell - sudo apt-get install apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring - ``` - -1. Download and add [NGINX signing key](https://cs.nginx.com/static/keys/nginx_signing.key): - - ```shell - wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null - ``` - -1. Create `apt` configuration `/etc/apt/apt.conf.d/90pkgs-nginx`: - - ``` - Acquire::https::pkgs.nginx.com::Verify-Peer "true"; - Acquire::https::pkgs.nginx.com::Verify-Host "true"; - Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt"; - Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key"; - ``` - -1. Add the `nginx-agent` repository: - - ```shell - echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/nginx-agent/ubuntu/ `lsb_release -cs` agent" \ - | sudo tee /etc/apt/sources.list.d/nginx-agent.list - ``` - -1. To install `nginx-agent`, run the following commands: - - ```shell - sudo apt update - sudo apt install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - - -### Installing NGINX Agent on Debian - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Install the prerequisites: - - ```shell - sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring - ``` - -1. Add the `nginx-agent` repository: - - ```shell - echo "deb https://pkgs.nginx.com/nginx-agent/debian/ `lsb_release -cs` agent" \ - | sudo tee /etc/apt/sources.list.d/nginx-agent.list - ``` - -1. Create apt configuration `/etc/apt/apt.conf.d/90pkgs-nginx`: - - ``` - Acquire::https::pkgs.nginx.com::Verify-Peer "true"; - Acquire::https::pkgs.nginx.com::Verify-Host "true"; - Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt"; - Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key"; - ``` - -1. To install `nginx-agent`, run the following commands: - - ```shell - sudo apt update - sudo apt install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on SLES - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Create a file bundle of the certificate and key: - - ```shell - cat /etc/ssl/nginx/nginx-repo.crt /etc/ssl/nginx/nginx-repo.key > /etc/ssl/nginx/nginx-repo-bundle.crt - ``` - -1. Install the prerequisites: - - ```shell - sudo zypper install curl ca-certificates gpg2 gawk - ``` - -1. To set up the zypper repository for `nginx-agent` packages, run the following command: - - ```shell - sudo zypper addrepo --refresh --check \ - 'https://pkgs.nginx.com/nginx-agent/sles/$releasever_major?ssl_clientcert=/etc/ssl/nginx/nginx-repo-bundle.crt&ssl_verify=peer' nginx-agent - ``` - -1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key: - - ```shell - curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key - ``` - -1. Verify that the downloaded file contains the proper key: - - ```shell - gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key - ``` - -1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: - - ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 - uid nginx signing key - ``` - -1. Finally, import the key to the rpm database: - - ```shell - sudo rpmkeys --import /tmp/nginx_signing.key - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo zypper install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on Alpine Linux - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/apk/` directory: - - ```shell - sudo cp nginx-repo.key /etc/apk/cert.key - sudo cp nginx-repo.crt /etc/apk/cert.pem - ``` - -1. Install the prerequisites: - - ```shell - sudo apk add openssl curl ca-certificates - ``` - -1. To set up the apk repository for `nginx-agent` packages, run the following command: - - ```shell - printf "%s%s%s\n" \ - "https://pkgs.nginx.com/nginx-agent/alpine/v" \ - `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \ - "/main" \ - | sudo tee -a /etc/apk/repositories - ``` - -1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key: - - ```shell - curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub - ``` - -1. Verify that downloaded file contains the proper key: - - ```shell - openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout - ``` - - The output should contain the following modulus: - - ``` - Public-Key: (2048 bit) - Modulus: - 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58: - 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70: - 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1: - f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab: - 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f: - 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64: - 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d: - 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3: - 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c: - 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34: - 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f: - 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17: - 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99: - 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67: - c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e: - ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4: - 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f: - ab:6d - Exponent: 65537 (0x10001) - ``` - -1. Finally, move the key to apk trusted keys storage: - - ```shell - sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/ - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo apk add nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on Amazon Linux - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the `nginx-repo.crt` and `nginx-repo.key` files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Install the prerequisites: - - ```shell - sudo yum install yum-utils procps ca-certificates - ``` - -1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: - - ``` - [nginx-agent] - name=nginx-agent repo - baseurl=https://pkgs.nginx.com/nginx-agent/amzn2/$releasever/$basearch - sslclientcert=/etc/ssl/nginx/nginx-repo.crt - sslclientkey=/etc/ssl/nginx/nginx-repo.key - gpgcheck=0 - enabled=1 - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo yum install nginx-agent - ``` - -1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` - -### Installing NGINX Agent on FreeBSD - -1. Create the `/etc/ssl/nginx` directory: - - ```shell - sudo mkdir -p /etc/ssl/nginx - ``` - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. - -1. Copy the files to the `/etc/ssl/nginx/` directory: - - ```shell - sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ - ``` - -1. Install the prerequisite `ca_root_nss` package: - - ```shell - sudo pkg install ca_root_nss - ``` - -1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content: - - ``` - nginx-agent: { - URL: pkg+https://pkgs.nginx.com/nginx-agent/freebsd/${ABI}/latest - ENABLED: yes - MIRROR_TYPE: SRV - } - ``` - -1. Add the following lines to the `/usr/local/etc/pkg.conf` file: - - ``` - PKG_ENV: { SSL_NO_VERIFY_PEER: "1", - SSL_CLIENT_CERT_FILE: "/etc/ssl/nginx/nginx-repo.crt", - SSL_CLIENT_KEY_FILE: "/etc/ssl/nginx/nginx-repo.key" } - ``` - -1. To install `nginx-agent`, run the following command: - - ```shell - sudo pkg install nginx-agent - ``` - -1. Verify the installation: - - ```shell - sudo nginx-agent -v - ``` diff --git a/site/content/installation-upgrade/uninstall.md b/site/content/installation-upgrade/uninstall.md deleted file mode 100644 index 0431f72bda..0000000000 --- a/site/content/installation-upgrade/uninstall.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: "Uninstall NGINX Agent package" -draft: false -weight: 700 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -Learn how to uninstall NGINX Agent from your system. - -## Prerequisites - -- NGINX Agent installed [NGINX Agent installed](../installation-oss) -- The user following these steps will need `root` privilege - -## Uninstalling NGINX Agent -Complete the following steps on each host where you’ve installed NGINX Agent - - -- [Uninstalling NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#uninstalling-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux) -- [Uninstalling NGINX Agent on Ubuntu](#uninstalling-nginx-agent-on-ubuntu) -- [Uninstalling NGINX Agent on Debian](#uninstalling-nginx-agent-on-debian) -- [Uninstalling NGINX Agent on SLES](#uninstalling-nginx-agent-on-sles) -- [Uninstalling NGINX Agent on Alpine Linux](#uninstalling-nginx-agent-on-alpine-linux) -- [Uninstalling NGINX Agent on Amazon Linux](#uninstalling-nginx-agent-on-amazon-linux) -- [Uninstalling NGINX Agent on FreeBSD](#uninstalling-nginx-agent-on-freebsd) - -### Uninstalling NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux - -Complete the following steps on each host where you've installed NGINX Agent: - -1. Stop NGINX Agent: - - ```bash - sudo systemctl stop nginx-agent - ``` - -2. To uninstall NGINX Agent, run the following command: - - ```bash - sudo yum remove nginx-agent - ``` - -### Uninstalling NGINX Agent on Ubuntu - -Complete the following steps on each host where you've installed NGINX Agent: - -1. Stop NGINX Agent: - - ```bash - sudo systemctl stop nginx-agent - ``` - -2. To uninstall NGINX Agent, run the following command: - - ```bash - sudo apt-get remove nginx-agent - ``` - - > **Note:** The `apt-get remove ` command will remove the package from your system, while keeping the associated configuration files for possible future use. If you want to completely remove the package and all of its configuration files, you should use `apt-get purge `. - -### Uninstalling NGINX Agent on Debian - -Complete the following steps on each host where you've installed NGINX Agent: - -1. Stop NGINX Agent: - - ```bash - sudo systemctl stop nginx-agent - ``` - -2. To uninstall NGINX Agent, run the following command: - - ```bash - sudo apt-get remove nginx-agent - ``` - - > **Note:** The `apt-get remove ` command will remove the package from your system, while keeping the associated configuration files for possible future use. If you want to completely remove the package and all of its configuration files, you should use `apt-get purge `. - -### Uninstalling NGINX Agent on SLES - -Complete the following steps on each host where you've installed NGINX Agent: - -1. Stop NGINX agent: - - ```bash - sudo systemctl stop nginx-agent - ``` - -2. To uninstall NGINX agent, run the following command: - - ```bash - sudo zypper remove nginx-agent - ``` - -### Uninstalling NGINX Agent on Alpine Linux - -Complete the following steps on each host where you've installed NGINX agent: - -1. Stop NGINX agent: - - ```bash - sudo rc-service nginx-agent stop - ``` - -2. To uninstall NGINX agent, run the following command: - - ```bash - sudo apk del nginx-agent - ``` - -### Uninstalling NGINX Agent on Amazon Linux - -Complete the following steps on each host where you've installed NGINX agent: - -1. Stop NGINX agent: - - ```bash - sudo systemctl stop nginx-agent - ``` - -2. To uninstall NGINX agent, run the following command: - - ```bash - sudo yum remove nginx-agent - ``` - -### Uninstalling NGINX Agent on FreeBSD - -Complete the following steps on each host where you've installed NGINX agent: - -1. Stop NGINX agent: - - ```bash - sudo service nginx-agent stop - ``` - -2. To uninstall NGINX agent, run the following command: - - ```bash - sudo pkg delete nginx-agent - ``` diff --git a/site/content/metrics.md b/site/content/metrics.md new file mode 100644 index 0000000000..179f413b96 --- /dev/null +++ b/site/content/metrics.md @@ -0,0 +1,5 @@ +--- +title: OpenTelemetry metrics +weight: 300 +docs: DOCS-000 +--- \ No newline at end of file diff --git a/site/content/overview.md b/site/content/overview.md deleted file mode 100644 index 76e16c8e69..0000000000 --- a/site/content/overview.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Overview" -draft: false -weight: 100 -toc: true -tags: [ "docs" ] -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus instance. It enables: - -- Remote management of NGINX configurations -- Collection and reporting of real-time NGINX performance and operating system metrics -- Notifications of NGINX events - - -{{< img src="grafana-dashboard-example.png" caption="Grafana dashboard showing metrics reported by NGINX Agent" alt="Grafana dashboard showing metrics reported by NGINX Agent" width="99%">}} - -## How it Works - -NGINX Agent runs as a companion process on a system running NGINX. It provides gRPC and REST interfaces for configuration management and metrics collection from the NGINX process and operating system. NGINX Agent enables remote interaction with NGINX using common Linux tools and unlocks the ability to build sophisticated monitoring and control systems that can manage large collections of NGINX instances. - -{{< img src="agent-flow.png" caption="How Agent works" alt="How NGINX Agent works" width="99%">}} - - -## Configuration Management - -NGINX Agent provides an API interface for submission of updated configuration files. Upon receipt of a new file, it checks the output of `nginx -V` to determine the location of existing configurations. It then validates the new configuration with `nginx -t` before applying it via a signal HUP to the NGINX master process. - -## Collecting Metrics - -NGINX Agent interfaces with NGINX process information and parses NGINX logs to calculate and report metrics. When interfacing with NGINX Plus, NGINX Agent pulls relevant information from the NGINX Plus API. Reported metrics may be aggregated by [Prometheus](https://prometheus.io/) and visualized with tools like [Grafana](https://grafana.com/). - -### NGINX Open Source - -When running alongside an open source instance of NGINX, NGINX Agent requires that NGINX Access and Error logs are turned on and contain all default variables. - -### NGINX Plus - -For NGINX Agent to work properly with an NGINX Plus instance, the API needs to be configured in that instance's nginx.conf. See [Instance Metrics Overview](https://docs.nginx.com/nginx-management-suite/nim/about/overview-metrics/) for more details. Once NGINX Plus is configured with the `/api/` endpoint, the Agent will automatically use it on startup. - -## Event Notifications - -NGINX Agent allows a gRPC connected control system to register a listener for a specific event. The control mechanism is then invoked when NGINX Agent sends an associated system signal. The source of a notification can be either the NGINX instance or NGINX Agent itself. Here's a list of currently supported events: - - -{{< raw-html>}}
{{}} -{{}} -| Event | Description | -| -------------------------------- | -------------------------------------------- | -| AGENT_START_MESSAGE | Agent process started | -| AGENT_STOP_MESSAGE | Agent process stopped | -| NGINX_FOUND_MESSAGE | NGINX master process detected on system | -| NGINX_STOP_MESSAGE | NGINX master process stopped | -| NGINX_RELOAD_SUCCESS_MESSAGE | NGINX master process reloaded successfully | -| NGINX_RELOAD_FAILED_MESSAGE | NGINX master process failed to reload | -| NGINX_WORKER_START_MESSAGE | New NGINX worker process started | -| NGINX_WORKER_STOP_MESSAGE | NGINX worker process stopped | -| CONFIG_APPLY_SUCCESS_MESSAGE | Successfully applied new NGINX configuration | -| CONFIG_APPLY_FAILURE_MESSAGE | Failed to apply new NGINX configuration | -| CONFIG_ROLLBACK_SUCCESS_MESSAGE | Successfully rolled back NGINX configuration | -| CONFIG_ROLLBACK_FAILURE_MESSAGE | Failed to roll back NGINX configuration | -{{}} -{{< raw-html>}}
{{}} - - diff --git a/site/content/previous-versions/NGINX-agent-v2/changelog.md b/site/content/previous-versions/NGINX-agent-v2/changelog.md deleted file mode 100644 index d4c587926b..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/changelog.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: "Changelog" -weight: 1200 -toc: true -docs: "DOCS-1093" ---- - -{{< note >}}You can find the full changelog, contributor list and assets for NGINX Agent in the [GitHub repository](https://github.com/nginx/agent/releases).{{< /note >}} - -See the list of supported Operating Systems and architectures in the [Technical Specifications]({{< relref "./technical-specifications.md" >}}). - ---- -## Release [v2.32.2](https//github.com/nginx/agent/releases/tag/v2.32.2) - -### 🌟 Highlights - -- This release fixes an issue where certain container runtimes were reporting as bare-metal hosts. - -### 🚀 Features - -This release introduces the following new features: - -- feat: improve docker docs by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#587](https://github.com/nginx/agent/pull/587) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix install-tools by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#581](https://github.com/nginx/agent/pull/581) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- change log updated for last release by [@oliveromahony](https://github.com/oliveromahony) in [#583](https://github.com/nginx/agent/pull/583) -- Restore agent container information from nms docs by [@jputrino](https://github.com/jputrino) in [#584](https://github.com/nginx/agent/pull/584) -- fix: add additional container checks during instance registration by [@mattdesmarais](https://github.com/mattdesmarais) in [#592](https://github.com/nginx/agent/pull/592) - ---- -## Release [v2.32.1](https//github.com/nginx/agent/releases/tag/v2.32.1) - -### 🚀 Features - -This release introduces the following new features: - -- feat: Agent Docs IA refactor by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#548](https://github.com/nginx/agent/pull/548) -- feat: move NMS agent docs by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#553](https://github.com/nginx/agent/pull/553) -- feat: import changelog from github by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#570](https://github.com/nginx/agent/pull/570) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- fix runners and bump go version by [@oliveromahony](https://github.com/oliveromahony) in [#550](https://github.com/nginx/agent/pull/550) -- Fix artifact name by [@oliveromahony](https://github.com/oliveromahony) in [#558](https://github.com/nginx/agent/pull/558) -- fix: add missing catalog entry by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#572](https://github.com/nginx/agent/pull/572) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- Runc bump by [@oliveromahony](https://github.com/oliveromahony) in [#565](https://github.com/nginx/agent/pull/565) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- bump vulnerable version of buildkit by [@oliveromahony](https://github.com/oliveromahony) in [#564](https://github.com/nginx/agent/pull/564) - ---- -## Release [v2.32.0](https//github.com/nginx/agent/releases/tag/v2.32.0) - -### 🚀 Features - -This release introduces the following new features: - -- feat: added the new OS support for NGINX R31 by [@oliveromahony](https://github.com/oliveromahony) in [#538](https://github.com/nginx/agent/pull/538) - ---- -## Release [v2.31.2](https//github.com/nginx/agent/releases/tag/v2.31.2) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- chore: rename hugo folder to site, fix product naming by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#527](https://github.com/nginx/agent/pull/527) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- Update upgrade documentation by [@dhurley](https://github.com/dhurley) in [#526](https://github.com/nginx/agent/pull/526) -- Bump the versions of containerd and go-git dependencies by [@dhurley](https://github.com/dhurley) in [#533](https://github.com/nginx/agent/pull/533) -- updated dependencies by [@oliveromahony](https://github.com/oliveromahony) in [#536](https://github.com/nginx/agent/pull/536) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- Bump crypto dependency from 0.14.0 to 0.17.0 by [@dhurley](https://github.com/dhurley) in [#532](https://github.com/nginx/agent/pull/532) - ---- -## Release [v2.31.1](https//github.com/nginx/agent/releases/tag/v2.31.1) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix permissions for log file and dynamic config directory by [@aphralG](https://github.com/aphralG) in [#517](https://github.com/nginx/agent/pull/517) -- Fix server example in sdk to have timeout by [@aphralG](https://github.com/aphralG) in [#518](https://github.com/nginx/agent/pull/518) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- Update SELinux Readme by [@aphralG](https://github.com/aphralG) in [#522](https://github.com/nginx/agent/pull/522) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- Replace mockgen by [@oliveromahony](https://github.com/oliveromahony) in [#524](https://github.com/nginx/agent/pull/524) -- Restrict config apply directory permissions by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#519](https://github.com/nginx/agent/pull/519) -- Restrict NAP file/dir permissions by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#516](https://github.com/nginx/agent/pull/516) - ---- -## Release [v2.31.0](https//github.com/nginx/agent/releases/tag/v2.31.0) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix otelcontrib version by [@oliveromahony](https://github.com/oliveromahony) in [#504](https://github.com/nginx/agent/pull/504) -- Fix user agent request header to have the correct agent version by [@dhurley](https://github.com/dhurley) in [#498](https://github.com/nginx/agent/pull/498) -- Fix alpine plus dockerfile on alpine>=3.17 by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#511](https://github.com/nginx/agent/pull/511) -- fix: avoid stopping nginx-agent service on package upgrade by [@defanator](https://github.com/defanator) in [#352](https://github.com/nginx/agent/pull/352) -- Fix SELinux Policy by [@aphralG](https://github.com/aphralG) in [#520](https://github.com/nginx/agent/pull/520) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- Add CLI arg to set dynamic config path by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#490](https://github.com/nginx/agent/pull/490) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- crossplane version bump by [@oliveromahony](https://github.com/oliveromahony) in [#512](https://github.com/nginx/agent/pull/512) -- Add commander retry lock by [@dhurley](https://github.com/dhurley) in [#502](https://github.com/nginx/agent/pull/502) -- Bump otel dependency version and fix github workflow for dependabot PRs by [@dhurley](https://github.com/dhurley) in [#515](https://github.com/nginx/agent/pull/515) - ---- -## Release [v2.30.3](https//github.com/nginx/agent/releases/tag/v2.30.3) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix dependabot issues by [@oliveromahony](https://github.com/oliveromahony) in [#503](https://github.com/nginx/agent/pull/503) - ---- -## Release [v2.30.1](https//github.com/nginx/agent/releases/tag/v2.30.1) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- fix: Tolerate additional fields in App Protect yaml files by [@edarzins](https://github.com/edarzins) in [#494](https://github.com/nginx/agent/pull/494) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- Update nginx-plus-go-client to stop 404 errors in NGINX access logs by [@dhurley](https://github.com/dhurley) in [#495](https://github.com/nginx/agent/pull/495) - ---- -## Release [v2.30.0](https//github.com/nginx/agent/releases/tag/v2.30.0) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix version for forked repo by [@dhurley](https://github.com/dhurley) in [#468](https://github.com/nginx/agent/pull/468) -- Fix integration tests by [@aphralG](https://github.com/aphralG) in [#478](https://github.com/nginx/agent/pull/478) -- Fix config apply by [@oliveromahony](https://github.com/oliveromahony) in [#480](https://github.com/nginx/agent/pull/480) -- deprecate system.mem.used.all metric by [@aphralG](https://github.com/aphralG) in [#485](https://github.com/nginx/agent/pull/485) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- Update CLI flags documentation by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#476](https://github.com/nginx/agent/pull/476) -- Update NGINX plugin to read NGINX config on startup by [@dhurley](https://github.com/dhurley) in [#489](https://github.com/nginx/agent/pull/489) - -### 🔨 Maintenance - -We have made the following maintenance-related minor changes: - -- Update file watcher to ignore .swx files by [@dhurley](https://github.com/dhurley) in [#466](https://github.com/nginx/agent/pull/466) -- Check Simplemetrics is not empty by [@aphralG](https://github.com/aphralG) in [#474](https://github.com/nginx/agent/pull/474) -- Add error log if duplicate NGINX IDs are found by [@dhurley](https://github.com/dhurley) in [#477](https://github.com/nginx/agent/pull/477) -- Add tests for additional SSL directives and key algorithms. [#276](https://github.com/nginx/agent/issues/276) by [@arsenalzp](https://github.com/arsenalzp) in [#469](https://github.com/nginx/agent/pull/469) -- call underlying os.Hostname instead of the entire hostInfo gopsutil call by [@oliveromahony](https://github.com/oliveromahony) in [#479](https://github.com/nginx/agent/pull/479) -- Add grpc integration tests by [@dhurley](https://github.com/dhurley) in [#475](https://github.com/nginx/agent/pull/475) -- remove error log causing failures by [@aphralG](https://github.com/aphralG) in [#488](https://github.com/nginx/agent/pull/488) -- Use singleflight for caching environment.go calls by [@oliveromahony](https://github.com/oliveromahony) in [#481](https://github.com/nginx/agent/pull/481) -- Reduce the number of times env.Processes gets called by [@dhurley](https://github.com/dhurley) in [#482](https://github.com/nginx/agent/pull/482) -- add additional check to nginxProcesses by [@aphralG](https://github.com/aphralG) in [#483](https://github.com/nginx/agent/pull/483) -- profile.cgo by [@oliveromahony](https://github.com/oliveromahony) in [#493](https://github.com/nginx/agent/pull/493) - diff --git a/site/content/previous-versions/NGINX-agent-v2/configuration/_index.md b/site/content/previous-versions/NGINX-agent-v2/configuration/_index.md deleted file mode 100644 index 3d1fdf4e34..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/configuration/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Configuration" -description: "Learn how to configure NGINX Agent." -linkTitle: "Configuration" -weight: "400" -menu: docs ---- \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/contribute/_index.md b/site/content/previous-versions/NGINX-agent-v2/contribute/_index.md deleted file mode 100644 index dc79b629a7..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/contribute/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Contribute" -description: "Learn about the NGINX Agent community and contribute to the project." -linkTitle: "Contribute" -menu: docs -weight: "500" ---- \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/contribute/community.md b/site/content/previous-versions/NGINX-agent-v2/contribute/community.md deleted file mode 100644 index 16763795dd..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/contribute/community.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "Community and Contribution" -draft: false -weight: 100 -toc: true -tags: [ "docs" ] -docs: "DOCS-1087" -categories: ["configuration"] -doctypes: ["task"] ---- - -# Community - -- Our [Slack channel #nginx-agent](https://nginxcommunity.slack.com/), is the go-to place to start asking questions and sharing your thoughts. - -- Our [GitHub issues page](https://github.com/nginx/agent/issues) offers space for a more technical discussion at your own pace. - -# Contribute - -Get involved with the project by contributing! Please see our [contributing guide](https://github.com/nginx/agent/blob/main/CONTRIBUTING.md) for details. - -# License - -[Apache License, Version 2.0](https://github.com/nginx/agent/blob/main/LICENSE) diff --git a/site/content/previous-versions/NGINX-agent-v2/contribute/dev-environment-setup.md b/site/content/previous-versions/NGINX-agent-v2/contribute/dev-environment-setup.md deleted file mode 100644 index e9e3e9db03..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/contribute/dev-environment-setup.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "Development Environment Setup" -draft: false -weight: 200 -toc: true -tags: [ "docs" ] - -categories: ["development"] -doctypes: ["task"] ---- - -## Overview - -Learn how to setup a Development Environment for NGINX Agent. - -## Select an Operating System - -While most Linux or FreeBSD operating systems can be used to contribute to the NGINX Agent project, the following steps have been designed for Ubuntu. Ubuntu is packaged with most libraries required to build and run NGINX Agent, and is the recommended platform for NGINX Agent development. - -## Install NGINX - -Follow the steps in the [Installation]({{< relref "/previous-versions/NGINX-agent-v2/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX and NGINX Agent. - -## Clone the NGINX Agent Repository - -Using your preferred method, clone the NGINX Agent repository into your development directory. See [Cloning a GitHub Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for additional help. - -## Installing Prerequisite Packages -Depending on the operating system distribution, it may be necessary to install the following packages in order to build NGINX Agent. - -Change to the NGINX Agent source directory: -```bash -cd /agent -``` - -Install Make: -```bash -sudo apt install make -``` - -NGINX Agent is written in Go. You may [download Go](https://go.dev/doc/install) and follow installation instructions on the same page or run: -```bash -sudo apt install golang-go -``` - -Install Protoc: -```bash -sudo apt install -y protobuf-compiler -``` - -Install NGINX Agent tools and dependencies: - -Before starting development on NGINX Agent, it is important to download and install the necessary tool and dependencies required by NGINX Agent. You can do this by running the following `make` command: -```bash -make install-tools deps -``` - -## Building NGINX Agent from Source Code - -Run the following commands to build and run NGINX Agent: - -```bash -make build -sudo make run -``` diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/_index.md b/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/_index.md deleted file mode 100644 index 211fc3e9b6..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Installation and Upgrade" -description: "Learn how to install, upgrade, and uninstall NGINX Agent." -menu: docs -weight: 300 ---- \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/_index.md b/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/_index.md deleted file mode 100644 index e2de9f52c2..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Container Environments" -description: "Learn how to build and run NGINX Agent docker images." -menu: docs -weight: 800 ---- \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/getting-started.md b/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/getting-started.md deleted file mode 100644 index e7f3e96d69..0000000000 --- a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/getting-started.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: "Getting Started" -draft: false -weight: 100 -toc: true -tags: [ "docs" ] -docs: "DOCS-1089" -categories: ["configuration"] -doctypes: ["task"] ---- - -## Overview - -Follow these steps to configure and run NGINX Agent and a mock interface ("control plane") to which NGINX Agent will report. - -## Install NGINX - -Follow the steps in the [Installation]({{< relref "/previous-versions/NGINX-agent-v2/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX. - -## Clone the NGINX Agent Repository - -Using your preferred method, clone the NGINX Agent repository into your development directory. See [Cloning a GitHub Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for additional help. - -## Install Go - -NGINX Agent and the Mock Control Plane are written in Go. Go 1.23.0 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/). - -## Start the gRPC Mock Control Plane - -Start the mock control plane by running the following command from the `agent` source code root directory: - -```shell -go run sdk/examples/server.go - -# Command Output -INFO[0000] http listening at 54790 # mock control plane port -INFO[0000] grpc listening at 54789 # grpc control plane port which NGINX Agent will report to -``` - -## NGINX Agent Settings - -If it doesn't already exist, create the `/etc/nginx-agent/` directory and copy the `nginx-agent.conf` file into it from the project root directory. - -```shell -sudo mkdir /etc/nginx-agent -sudo cp /nginx-agent.conf /etc/nginx-agent/ -``` - -Create the `agent-dynamic.conf` file, which is required for NGINX Agent to run. - -In Linux environments: -```shell -sudo touch /var/lib/nginx-agent/agent-dynamic.conf -``` - -In FreeBSD environments: -```shell -sudo touch /var/db/nginx-agent/agent-dynamic.conf -``` - -### Enable the gRPC interface - -Add the the following settings to `/etc/nginx-agent/nginx-agent.conf`: - -```yaml -server: - host: 127.0.0.1 # mock control plane host - grpcPort: 54789 # mock control plane gRPC port - -# gRPC TLS options - DISABLING TLS IS NOT RECOMMENDED FOR PRODUCTION -tls: - enable: false - skip_verify: true -``` - -For more information, see [Agent Protocol Definitions and Documentation](https://github.com/nginx/agent/tree/main/docs/proto/README.md). - -### Enable the REST interface - -The NGINX Agent REST interface can be exposed by validating the following lines in the `/etc/nginx-agent/nginx-agent.conf` file are present: - -```yaml -api: - # Set API address to allow remote management - host: 127.0.0.1 - # Set this value to a secure port number to prevent information leaks - port: 8038 - # REST TLS parameters - cert: ".crt" - key: ".key" -``` - -The mock control plane can use either gRPC or REST protocols to communicate with NGINX Agent. - -## Launch Swagger UI - -Swagger UI requires goswagger be installed. See [instructions for installing goswagger](https://goswagger.io/install.html) for additional help. - -To launch the Swagger UI for the REST interface run the following command: - -```shell -make launch-swagger-ui -``` - -## Extensions - -An extension is a piece of code, not critical to the main functionality that NGINX agent is responsible for. This generally falls outside the remit of managing NGINX Configuration and reporting NGINX metrics. - -To enable an extension, it must be added to the extensions list in the `/etc/nginx-agent/nginx-agent.conf`. -Here is an example of enabling the advanced metrics extension: - -```yaml -extensions: - - advanced-metrics -``` - -## Start NGINX Agent - -If already running, restart NGINX Agent to apply the new configuration. Alternatively, if NGINX Agent is not running, you may run it from the source code root directory. - -Open another terminal window and start NGINX Agent. Issue the following command from the `agent` source code root directory. - -```shell -sudo make run - -# Command Output snippet -WARN[0000] Log level is info -INFO[0000] setting displayName to XXX -INFO[0000] NGINX Agent at with pid 12345, clientID=XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX name=XXX -INFO[0000] NginxBinary initializing -INFO[0000] Commander initializing -INFO[0000] Comms initializing -INFO[0000] OneTimeRegistration initializing -INFO[0000] Registering XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX -INFO[0000] Metrics initializing -INFO[0000] MetricsThrottle initializing -INFO[0000] DataPlaneStatus initializing -INFO[0000] MetricsThrottle waiting for report ready -INFO[0000] Metrics waiting for handshake to be completed -INFO[0000] ProcessWatcher initializing -INFO[0000] Extensions initializing -INFO[0000] FileWatcher initializing -INFO[0000] FileWatchThrottle initializing -INFO[0001] Events initializing -INFO[0001] OneTimeRegistration completed -``` - -Open a web browser to view the mock control plane at [http://localhost:54790](http://localhost:54790). The following links will be shown in the web interface: - -- **registered** - shows registration information of the data plane -- **nginxes** - lists the nginx instances on the data plane -- **configs** - shows the protobuf payload for NGINX configuration sent to the management plane -- **configs/chunked** - shows the split-up payloads sent to the management plane -- **configs/raw** - shows the actual configuration as it would live on the data plane -- **metrics** - shows a buffer of metrics sent to the management plane (similar to what will be sent back in the REST API) - -For more NGINX Agent use cases, refer to the [NGINX Agent SDK examples](https://github.com/nginx/agent/tree/main/sdk/examples). - -## Start and Enable Start on Boot - -To start NGINX Agent on `systemd` systems, run the following command: - -```shell -sudo systemctl start nginx-agent -``` - -To enable NGINX Agent to start on boot, run the following command: - -```shell -sudo systemctl enable nginx-agent -``` - -## Logs - -NGINX Agent uses formatted log files to collect metrics. Expanding log formats and instance counts will also increase the size of the NGINX Agent log files. We recommend adding a separate partition for `/var/log/nginx-agent`. - -{{< important >}} -Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services. - -For more information, see [NGINX Agent Log Rotation]({{< relref "configuration/configuration-overview.md#nginx-agent-log-rotation" >}}). -{{< /important >}} diff --git a/site/content/previous-versions/_index.md b/site/content/previous-versions/_index.md deleted file mode 100644 index 8e47a7385c..0000000000 --- a/site/content/previous-versions/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Previous Versions" -description: "Documentation for previous versions of NGINX Agent." -linkTitle: "Previous Versions" -weight: 10000 ---- \ No newline at end of file diff --git a/site/content/support.md b/site/content/support.md new file mode 100644 index 0000000000..0c7fff1bfe --- /dev/null +++ b/site/content/support.md @@ -0,0 +1,15 @@ +--- +title: Support +weight: 800 +docs: DOCS-000 +--- + +## Support policy +F5 NGINX Agent adheres to the support policy detailed in the following knowledge base article: [K000140156](https://my.f5.com/manage/s/article/K000140156). + +## Contact F5 Support +For questions and/or assistance with installing, troubleshooting, or using NGINX Agent, contact Support via the [MyF5 Customer Portal](https://account.f5.com/myf5). + +## Community support +- If you experience issues with NGINX Agent, please [open an issue in GitHub](https://github.com/nginx/agent/issues/new). +- If you have any suggestions or feature requests, please [open an idea in GitHub discussions](https://github.com/nginx/agent/discussions). \ No newline at end of file diff --git a/site/content/technical-specifications.md b/site/content/technical-specifications.md index 6f9a72b091..fac11fbdc0 100644 --- a/site/content/technical-specifications.md +++ b/site/content/technical-specifications.md @@ -1,18 +1,15 @@ --- title: "Technical specifications" -draft: false -weight: 200 toc: true -tags: [ "docs" ] -categories: ["development"] -doctypes: ["task"] +weight: 200 +docs: DOCS-000 --- ## Overview -This document provides technical specifications for NGINX Agent. It includes information on supported distributions, deployment environments, NGINX versions, sizing recommendations, and logging. +This document provides technical specifications for F5 NGINX Agent. It includes information on supported distributions, deployment environments, NGINX versions, sizing recommendations, and logging. -## Supported Distributions +## Supported distributions NGINX Agent can run in most environments. We support the following distributions: @@ -31,7 +28,7 @@ NGINX Agent can run in most environments. We support the following distributions {{< /bootstrap-table >}} -## Supported Deployment Environments +## Supported deployment environments NGINX Agent can be deployed in the following environments: @@ -40,12 +37,12 @@ NGINX Agent can be deployed in the following environments: - Public Cloud: AWS, Google Cloud Platform, and Microsoft Azure - Virtual Machine -## Supported NGINX Versions +## Supported NGINX versions NGINX Agent works with all supported versions of NGINX Open Source and NGINX Plus. -## Sizing Recommendations +## Sizing recommendations Minimum system sizing recommendations for NGINX Agent: {{< bootstrap-table "table table-striped table-bordered" >}} @@ -56,4 +53,8 @@ Minimum system sizing recommendations for NGINX Agent: ## Logging -NGINX Agent utilizes log files and formats to collect metrics. Increasing the log formats and instance counts will result in increased log file sizes. To prevent system storage issues due to a growing log directory, it is recommended to add a separate partition for `/var/log/nginx-agent` and enable [log rotation](http://nginx.org/en/docs/control.html#logs). \ No newline at end of file +NGINX Agent utilizes log files and formats to collect metrics. Increasing the log formats and instance counts will result in increased log file sizes. + +To prevent system storage issues due to a growing log directory, it is recommended to add a separate partition for `/var/log/nginx-agent` and enable [log rotation](http://nginx.org/en/docs/control.html#logs). + +More information is available in the [Configuration overview]({{< ref "/how-to/configuration-overview.md#logs" >}}) \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/_index.md b/site/content/v2/_index.md similarity index 72% rename from site/content/previous-versions/NGINX-agent-v2/_index.md rename to site/content/v2/_index.md index 979f7a4c74..f0138d948b 100644 --- a/site/content/previous-versions/NGINX-agent-v2/_index.md +++ b/site/content/v2/_index.md @@ -1,6 +1,7 @@ --- title: "NGINX Agent v2" description: "NGINX Agent is a companion daemon for your NGINX Open Source or NGINX Plus instance." -linkTitle: "NGINX Agent" -menu: docs +weight: 900 +cascade: + type: agent-v2-migration --- \ No newline at end of file diff --git a/site/content/v2/changelog.md b/site/content/v2/changelog.md new file mode 100644 index 0000000000..3885df6635 --- /dev/null +++ b/site/content/v2/changelog.md @@ -0,0 +1,264 @@ +--- +title: "Changelog" +weight: 1200 +toc: true +docs: "DOCS-1093" +--- + +{{< note >}}You can find the full changelog, contributor list and assets for NGINX Agent in the [GitHub repository](https://github.com/nginx/agent/releases).{{< /note >}} + +See the list of supported Operating Systems and architectures in the [Technical Specifications]({{< relref "./technical-specifications.md" >}}). + +--- +## Release [v2.38.0](https://github.com/nginx/agent/releases/tag/v2.38.0) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Fix broken URLS in docs by [@nginx-aoife](https://github.com/nginx-aoife) in [#796](https://github.com/nginx/agent/pull/796) +- fix name of deprecated flag by [@aphralG](https://github.com/aphralG) in [#811](https://github.com/nginx/agent/pull/811) +- Fix make image targets by [@dhurley](https://github.com/dhurley) in [#812](https://github.com/nginx/agent/pull/812) +- Fix debian oss image by [@dhurley](https://github.com/dhurley) in [#819](https://github.com/nginx/agent/pull/819) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- docs: update GPG keys by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#776](https://github.com/nginx/agent/pull/776) +- Add new docker images to v2 pipeline for integration testing by [@oliveromahony](https://github.com/oliveromahony) in [#756](https://github.com/nginx/agent/pull/756) +- Update website changelog for v2.37.0 by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#790](https://github.com/nginx/agent/pull/790) +- Pass on custom error log path at the time of validating config by [@achawla2012](https://github.com/achawla2012) in [#774](https://github.com/nginx/agent/pull/774) +- Remove blocking calls in metrics framework by [@oliveromahony](https://github.com/oliveromahony) in [#788](https://github.com/nginx/agent/pull/788) +- Update broken URL in installation-plus.md by [@nginx-aoife](https://github.com/nginx-aoife) in [#808](https://github.com/nginx/agent/pull/808) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- add new plus docker images to v2 pipeline by [@aphralG](https://github.com/aphralG) in [#779](https://github.com/nginx/agent/pull/779) +- Add MaxRecvMsgSize and MaxSendMsgSize to client and server options by [@oliveromahony](https://github.com/oliveromahony) in [#795](https://github.com/nginx/agent/pull/795) +- added leak tests for agent v2 by [@oliveromahony](https://github.com/oliveromahony) in [#807](https://github.com/nginx/agent/pull/807) + +--- +## Release [v2.37.0](https://github.com/nginx/agent/releases/tag/v2.37.0) + +### 🚀 Features + +This release introduces the following new features: + +- feat: Update the changelog by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#753](https://github.com/nginx/agent/pull/753) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Prevent writing outside allowed directories list from a config payload with actions by [@oliveromahony](https://github.com/oliveromahony) in [#766](https://github.com/nginx/agent/pull/766) +- The letter v is now always prepended to output of -v by [@olli-holmala](https://github.com/olli-holmala) in [#751](https://github.com/nginx/agent/pull/751) +- Fix backoff to drop Metrics Reports from buffer after max_elapsed_time has been reached by [@oliveromahony](https://github.com/oliveromahony) in [#752](https://github.com/nginx/agent/pull/752) +- Fix Post Install Script Issues by [@spencerugbo](https://github.com/spencerugbo) in [#739](https://github.com/nginx/agent/pull/739) +- docs: fix github links in changelog by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#770](https://github.com/nginx/agent/pull/770) +- Fix post install script for when no nginx instance is installed by [@dhurley](https://github.com/dhurley) in [#773](https://github.com/nginx/agent/pull/773) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- Upgrade prometheus exporter version to latest by [@oliveromahony](https://github.com/oliveromahony) in [#749](https://github.com/nginx/agent/pull/749) +- Add badges for Go version, release, license, contributions, and Slack… by [@oCHRISo](https://github.com/oCHRISo) in [#763](https://github.com/nginx/agent/pull/763) +- Add instructions for Amazon Linux 2023 by [@nginx-seanmoloney](https://github.com/nginx-seanmoloney) in [#759](https://github.com/nginx/agent/pull/759) +- Add docs-build-push github workflow by [@nginx-jack](https://github.com/nginx-jack) in [#765](https://github.com/nginx/agent/pull/765) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- Increase timeout period for collecting metrics by [@oliveromahony](https://github.com/oliveromahony) in [#755](https://github.com/nginx/agent/pull/755) + +--- +## Release [v2.36.1](https://github.com/nginx/agent/releases/tag/v2.36.1) + +### 🌟 Highlights + +- Upgrade crossplane version to prevent Agent from rolling back in the case of valid NGINX configurations by [@oliveromahony](https://github.com/oliveromahony) in [#746](https://github.com/nginx/agent/pull/746) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- Added version regex to parse the logs to see if matches vsemvar format by [@oliveromahony](https://github.com/oliveromahony) in [#747](https://github.com/nginx/agent/pull/747) + +--- +## Release [v2.36.0](https://github.com/nginx/agent/releases/tag/v2.36.0) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Fix incorrect bold tag in heading by [@nginx-seanmoloney](https://github.com/nginx-seanmoloney) in [#715](https://github.com/nginx/agent/pull/715) +- URL fix for building docker image in README.md by [@y82](https://github.com/y82) in [#720](https://github.com/nginx/agent/pull/720) +- Fix for version by [@oliveromahony](https://github.com/oliveromahony) in [#732](https://github.com/nginx/agent/pull/732) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- More flexible container images for the official images by [@oliveromahony](https://github.com/oliveromahony) in [#729](https://github.com/nginx/agent/pull/729) +- Update configuration examples by [@nginx-seanmoloney](https://github.com/nginx-seanmoloney) in [#731](https://github.com/nginx/agent/pull/731) +- updated github.com/rs/cors version by [@oliveromahony](https://github.com/oliveromahony) in [#735](https://github.com/nginx/agent/pull/735) +- docs: update changelog by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#736](https://github.com/nginx/agent/pull/736) +- Upgrade crossplane by [@oliveromahony](https://github.com/oliveromahony) in [#737](https://github.com/nginx/agent/pull/737) + +--- +## Release [v2.35.1](https://github.com/nginx/agent/releases/tag/v2.35.1) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- fix: add deduplication for the same ssl cert metadata by [@mattdesmarais](https://github.com/mattdesmarais) [@oliveromahony](https://github.com/oliveromahony) in [#716](https://github.com/nginx/agent/pull/716) +- Fix release workflow by [@dhurley](https://github.com/dhurley) in [#724](https://github.com/nginx/agent/pull/724) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- Update environment variables from NMS to NGINX_AGENT by [@spencerugbo](https://github.com/spencerugbo) in [#710](https://github.com/nginx/agent/pull/710) +- Update the flag & environment table callouts by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#712](https://github.com/nginx/agent/pull/712) +- updated golang version to 1.22 by [@oliveromahony](https://github.com/oliveromahony) in [#717](https://github.com/nginx/agent/pull/717) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- More detailed test for env variables migration by [@oliveromahony](https://github.com/oliveromahony) in [#709](https://github.com/nginx/agent/pull/709) + +--- +## Release [v2.35.0](https://github.com/nginx/agent/releases/tag/v2.35.0) + +### 🌟 Highlights + +- R32 operating system support parity by [@oliveromahony](https://github.com/oliveromahony) in [#708](https://github.com/nginx/agent/pull/708) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Change environment prefix from nms to nginx_agent by [@spencerugbo](https://github.com/spencerugbo) in [#706](https://github.com/nginx/agent/pull/706) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- Consolidated CLI flag and Env Var sections by [@travisamartin](https://github.com/travisamartin) in [#701](https://github.com/nginx/agent/pull/701) +- Add Ubuntu Noble 24.04 LTS support by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#682](https://github.com/nginx/agent/pull/682) + +--- +## Release [v2.34.1](https://github.com/nginx/agent/releases/tag/v2.34.1) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Fix metrics reporter retry logic by [@dhurley](https://github.com/dhurley) in [#700](https://github.com/nginx/agent/pull/700) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- Update changelog for release 2.34 by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#693](https://github.com/nginx/agent/pull/693) + +--- +## Release [v2.34.0](https://github.com/nginx/agent/releases/tag/v2.34.0) + +### 🌟 Highlights + +- Bump the version of net package in golang by [@oliveromahony](https://github.com/oliveromahony) in [#645](https://github.com/nginx/agent/pull/645) + +- Add health check endpoint by [@dhurley](https://github.com/dhurley) in [#665](https://github.com/nginx/agent/pull/665) + +- Add pending health status by [@dhurley](https://github.com/dhurley) in [#672](https://github.com/nginx/agent/pull/672) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- fix: fix titles case by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#674](https://github.com/nginx/agent/pull/674) +- Fix oracle linux integration test by [@dhurley](https://github.com/dhurley) in [#676](https://github.com/nginx/agent/pull/676) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- chore: add 2.33.0 changelog by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#622](https://github.com/nginx/agent/pull/622) +- Change environment variable list to table with CLI references by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#689](https://github.com/nginx/agent/pull/689) +- Add health checks documentation by [@dhurley](https://github.com/dhurley) in [#673](https://github.com/nginx/agent/pull/673) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- Keep looking for master process by [@spencerugbo](https://github.com/spencerugbo) in [#617](https://github.com/nginx/agent/pull/617) +- Bump docker dependency to version v24.0.9 by [@dhurley](https://github.com/dhurley) in [#626](https://github.com/nginx/agent/pull/626) +- Bump the version of github.com/opencontainers/runc dependency by [@dhurley](https://github.com/dhurley) in [#657](https://github.com/nginx/agent/pull/657) +- Remove unnecessary freebsd logic for finding process executable by [@dhurley](https://github.com/dhurley) in [#668](https://github.com/nginx/agent/pull/668) +- Add additional checks in chunking functionality by [@dhurley](https://github.com/dhurley) in [#671](https://github.com/nginx/agent/pull/671) + +--- +## Release [v2.33.0](https://github.com/nginx/agent/releases/tag/v2.33.0) + +### 🚀 Features + +This release introduces the following new features: + +- feat: Add Support for NAP 5 by [@edarzins](https://github.com/edarzins) in [#604](https://github.com/nginx/agent/pull/604) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Fix nfpm.yaml for apk packages by [@dhurley](https://github.com/dhurley) in [#597](https://github.com/nginx/agent/pull/597) +- fix unit test by [@oliveromahony](https://github.com/oliveromahony) in [#607](https://github.com/nginx/agent/pull/607) +- Fix user workflow performance tests by [@dhurley](https://github.com/dhurley) in [#612](https://github.com/nginx/agent/pull/612) +- fix Advanced Metrics by [@aphralG](https://github.com/aphralG) in [#598](https://github.com/nginx/agent/pull/598) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- chore: Add the 2.32.2 Changelog to the docs website by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#601](https://github.com/nginx/agent/pull/601) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- Bump the version of protobuf by [@oliveromahony](https://github.com/oliveromahony) in [#602](https://github.com/nginx/agent/pull/602) +- replace duplicate isContainer call by [@oliveromahony](https://github.com/oliveromahony) in [#596](https://github.com/nginx/agent/pull/596) +- Add logging to NGINX API http requests by [@dhurley](https://github.com/dhurley) in [#605](https://github.com/nginx/agent/pull/605) + +--- +## Release [v2.32.2](https://github.com/nginx/agent/releases/tag/v2.32.2) + +### 🌟 Highlights + +- This release fixes an issue where certain container runtimes were reporting as bare-metal hosts. + +### 🚀 Features + +This release introduces the following new features: + +- feat: improve docker docs by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#587](https://github.com/nginx/agent/pull/587) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Fix install-tools by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#581](https://github.com/nginx/agent/pull/581) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- change log updated for last release by [@oliveromahony](https://github.com/oliveromahony) in [#583](https://github.com/nginx/agent/pull/583) +- Restore agent container information from nms docs by [@jputrino](https://github.com/jputrino) in [#584](https://github.com/nginx/agent/pull/584) +- fix: add additional container checks during instance registration by [@mattdesmarais](https://github.com/mattdesmarais) in [#592](https://github.com/nginx/agent/pull/592) diff --git a/site/content/v2/configuration/_index.md b/site/content/v2/configuration/_index.md new file mode 100644 index 0000000000..cd9db7e495 --- /dev/null +++ b/site/content/v2/configuration/_index.md @@ -0,0 +1,6 @@ +--- +title: "Configuration" +weight: "400" +--- + +Learn how to configure NGINX Agent. \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/configuration/configuration-overview.md b/site/content/v2/configuration/configuration-overview.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/configuration/configuration-overview.md rename to site/content/v2/configuration/configuration-overview.md diff --git a/site/content/previous-versions/NGINX-agent-v2/configuration/configure-nginx-agent-group.md b/site/content/v2/configuration/configure-nginx-agent-group.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/configuration/configure-nginx-agent-group.md rename to site/content/v2/configuration/configure-nginx-agent-group.md diff --git a/site/content/previous-versions/NGINX-agent-v2/configuration/encrypt-communication.md b/site/content/v2/configuration/encrypt-communication.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/configuration/encrypt-communication.md rename to site/content/v2/configuration/encrypt-communication.md diff --git a/site/content/v2/installation-upgrade/_index.md b/site/content/v2/installation-upgrade/_index.md new file mode 100644 index 0000000000..9419e71857 --- /dev/null +++ b/site/content/v2/installation-upgrade/_index.md @@ -0,0 +1,7 @@ +--- +title: "Installation and Upgrade" +menu: docs +weight: 300 +--- + +Learn how to install, upgrade, and uninstall NGINX Agent. \ No newline at end of file diff --git a/site/content/v2/installation-upgrade/container-environments/_index.md b/site/content/v2/installation-upgrade/container-environments/_index.md new file mode 100644 index 0000000000..939ba9d18e --- /dev/null +++ b/site/content/v2/installation-upgrade/container-environments/_index.md @@ -0,0 +1,6 @@ +--- +title: "Container Environments" +weight: 800 +--- + +Learn how to build and run NGINX Agent docker images. \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-images.md b/site/content/v2/installation-upgrade/container-environments/docker-images.md similarity index 99% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-images.md rename to site/content/v2/installation-upgrade/container-environments/docker-images.md index cb164f60a6..749bb7128d 100644 --- a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-images.md +++ b/site/content/v2/installation-upgrade/container-environments/docker-images.md @@ -163,7 +163,7 @@ Here is an example of how to run the NGINX Agent container using Docker: docker run --name nginx-agent -d nginx-agent ``` -{{}}To learn more about the configuration options, refer to the NGINX Agent [Configuration Overview]({{< relref "/configuration/configuration-overview" >}}).{{}} +{{}}To learn more about the configuration options, refer to the NGINX Agent [Configuration Overview]({{< relref "/how-to/configuration-overview.md" >}}).{{}} ### Enable the gRPC interface diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-support.md b/site/content/v2/installation-upgrade/container-environments/docker-support.md similarity index 92% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-support.md rename to site/content/v2/installation-upgrade/container-environments/docker-support.md index 7123d9ee12..7736fa9512 100644 --- a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/container-environments/docker-support.md +++ b/site/content/v2/installation-upgrade/container-environments/docker-support.md @@ -12,7 +12,7 @@ docs: "DOCS-909" ## Overview -The NGINX Agent repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that can be used to [build custom container images]({{< relref "installation-upgrade/container-environments/docker-images.md" >}}). Images are created with an NGINX Open Source or NGINX Plus instance and are available for various operating systems. +The NGINX Agent repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that can be used to [build custom container images]({{< relref "/v2/installation-upgrade/container-environments/docker-images.md" >}}). Images are created with an NGINX Open Source or NGINX Plus instance and are available for various operating systems. See the [Technical Specifications]({{< relref "/technical-specifications.md#container-support" >}}) for a list of supported operationg systems. diff --git a/site/content/installation-upgrade/getting-started.md b/site/content/v2/installation-upgrade/getting-started.md similarity index 97% rename from site/content/installation-upgrade/getting-started.md rename to site/content/v2/installation-upgrade/getting-started.md index e3be8c8095..541d43299b 100644 --- a/site/content/installation-upgrade/getting-started.md +++ b/site/content/v2/installation-upgrade/getting-started.md @@ -1,9 +1,10 @@ --- -title: "Getting started" +title: "Getting Started" draft: false weight: 100 toc: true tags: [ "docs" ] +docs: "DOCS-1089" categories: ["configuration"] doctypes: ["task"] --- @@ -14,7 +15,7 @@ Follow these steps to configure and run NGINX Agent and a mock interface ("contr ## Install NGINX -Follow the steps in the [Installation]({{< relref "/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX. +Follow the steps in the [Installation]({{< ref "/v2/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX. ## Clone the NGINX Agent Repository @@ -176,5 +177,5 @@ NGINX Agent uses formatted log files to collect metrics. Expanding log formats a {{< important >}} Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services. -For more information, see [NGINX Agent Log Rotation]({{< relref "configuration/configuration-overview.md#nginx-agent-log-rotation" >}}). -{{< /important >}} +For more information, see [NGINX Agent Log Rotation]({{< relref "/how-to/configuration-overview.md#nginx-agent-log-rotation" >}}). +{{< /important >}} \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-github.md b/site/content/v2/installation-upgrade/installation-github.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-github.md rename to site/content/v2/installation-upgrade/installation-github.md diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-oss.md b/site/content/v2/installation-upgrade/installation-oss.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-oss.md rename to site/content/v2/installation-upgrade/installation-oss.md diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-plus.md b/site/content/v2/installation-upgrade/installation-plus.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/installation-plus.md rename to site/content/v2/installation-upgrade/installation-plus.md diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/uninstall.md b/site/content/v2/installation-upgrade/uninstall.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/uninstall.md rename to site/content/v2/installation-upgrade/uninstall.md diff --git a/site/content/previous-versions/NGINX-agent-v2/installation-upgrade/upgrade.md b/site/content/v2/installation-upgrade/upgrade.md similarity index 100% rename from site/content/previous-versions/NGINX-agent-v2/installation-upgrade/upgrade.md rename to site/content/v2/installation-upgrade/upgrade.md diff --git a/site/content/v2/metrics.md b/site/content/v2/metrics.md new file mode 100644 index 0000000000..e90e55c931 --- /dev/null +++ b/site/content/v2/metrics.md @@ -0,0 +1,10 @@ +--- +title: Metrics +catalog: true +catalogType: v2metrics +toc: true +weight: 200 +docs: DOCS-000 +--- + +{{< v2-metrics >}} \ No newline at end of file diff --git a/site/content/previous-versions/NGINX-agent-v2/technical-specifications.md b/site/content/v2/technical-specifications.md similarity index 87% rename from site/content/previous-versions/NGINX-agent-v2/technical-specifications.md rename to site/content/v2/technical-specifications.md index 52864eaa48..efa731527b 100644 --- a/site/content/previous-versions/NGINX-agent-v2/technical-specifications.md +++ b/site/content/v2/technical-specifications.md @@ -1,16 +1,13 @@ --- -title: "Technical Specifications" -draft: false -description: "This document describes the requirements for NGINX Agent." -weight: 200 +title: "Technical specifications" +weight: 100 toc: true -tags: [ "docs" ] docs: "DOCS-1092" -categories: ["development"] -doctypes: ["task"] --- -## Supported Distributions +This document describes the requirements for NGINX Agent v2. + +## Supported distributions NGINX Agent can run in most environments. We support the following distributions: @@ -29,7 +26,7 @@ NGINX Agent can run in most environments. We support the following distributions {{< /bootstrap-table >}} -## Supported Deployment Environments +## Supported deployment environments NGINX Agent can be deployed in the following environments: @@ -38,12 +35,12 @@ NGINX Agent can be deployed in the following environments: - Public Cloud: AWS, Google Cloud Platform, and Microsoft Azure - Virtual Machine -## Supported NGINX Versions +## Supported NGINX versions NGINX Agent works with all supported versions of NGINX Open Source and NGINX Plus. -## Sizing Recommendations +## Sizing recommendations Minimum system sizing recommendations for NGINX Agent: {{< bootstrap-table "table table-striped table-bordered" >}} From 8d5db500271f201e96cd07095bf7e9b84a9f4e1e Mon Sep 17 00:00:00 2001 From: Jon Cahill-Torre Date: Thu, 21 Nov 2024 18:05:40 +0000 Subject: [PATCH 2/7] docs: add files updated in main and layouts --- site/content/v2/changelog.md | 70 +++-- .../configuration/configuration-overview.md | 215 ++++++++-------- .../configure-nginx-agent-group.md | 2 +- .../v2/configuration/encrypt-communication.md | 20 +- .../content/v2/configuration/health-checks.md | 62 +++++ .../content/v2/installation-upgrade/_index.md | 7 +- .../container-environments/_index.md | 8 +- .../container-environments/docker-images.md | 239 +++--------------- .../container-environments/docker-support.md | 6 +- .../installation-upgrade/getting-started.md | 12 +- .../installation-github.md | 6 +- .../installation-upgrade/installation-oss.md | 101 ++++++-- .../installation-upgrade/installation-plus.md | 77 +++++- .../v2/installation-upgrade/uninstall.md | 29 ++- .../v2/installation-upgrade/upgrade.md | 2 +- site/go.mod | 2 +- site/go.sum | 2 + site/layouts/agent-v2-migration/list.html | 10 + site/layouts/agent-v2-migration/single.html | 49 ++++ site/layouts/catalogs/single.html | 14 + .../agent-v2-migration/list-main.html | 53 ++++ site/layouts/shortcodes/v2-metrics.html | 56 ++++ 22 files changed, 632 insertions(+), 410 deletions(-) create mode 100644 site/content/v2/configuration/health-checks.md create mode 100644 site/layouts/agent-v2-migration/list.html create mode 100644 site/layouts/agent-v2-migration/single.html create mode 100644 site/layouts/catalogs/single.html create mode 100644 site/layouts/partials/agent-v2-migration/list-main.html create mode 100644 site/layouts/shortcodes/v2-metrics.html diff --git a/site/content/v2/changelog.md b/site/content/v2/changelog.md index 3885df6635..981348f9e3 100644 --- a/site/content/v2/changelog.md +++ b/site/content/v2/changelog.md @@ -9,6 +9,50 @@ docs: "DOCS-1093" See the list of supported Operating Systems and architectures in the [Technical Specifications]({{< relref "./technical-specifications.md" >}}). +--- +## Release [v2.39.0](https://github.com/nginx/agent/releases/tag/v2.39.0) + +### 🌟 Highlights + +- Remove official docker images & move testing images to test folder by [@aphralG](https://github.com/aphralG) in [#838](https://github.com/nginx/agent/pull/838) + +### 🐛 Bug Fixes + +In this release we have resolved the following issues: + +- Race conditions fixes by [@oliveromahony](https://github.com/oliveromahony) in [#810](https://github.com/nginx/agent/pull/810) +- fix r30 pipeline failures by [@oliveromahony](https://github.com/oliveromahony) in [#844](https://github.com/nginx/agent/pull/844) +- Fixed make target pointing at wrong Dockerfile and renamed others to be consistent by [@oliveromahony](https://github.com/oliveromahony) in [#857](https://github.com/nginx/agent/pull/857) +- Fix broken links causing deployment failures by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#863](https://github.com/nginx/agent/pull/863) +- Fix NGINX OSS integration tests by [@dhurley](https://github.com/dhurley) in [#888](https://github.com/nginx/agent/pull/888) +- Fix docs docker failing without git context by [@nginx-jack](https://github.com/nginx-jack) in [#892](https://github.com/nginx/agent/pull/892) + +### 📝 Documentation + +We have made the following updates to the documentation: + +- Add automatic changelog generation in release workflow by [@spencerugbo](https://github.com/spencerugbo) in [#784](https://github.com/nginx/agent/pull/784) +- Add CLA bot workflow by [@lucacome](https://github.com/lucacome) in [#828](https://github.com/nginx/agent/pull/828) +- Refactor docker images by [@nginx-seanmoloney](https://github.com/nginx-seanmoloney) in [#841](https://github.com/nginx/agent/pull/841) +- Docs: Add hugo version check and theme update to Makefile by [@nginx-jack](https://github.com/nginx-jack) in [#869](https://github.com/nginx/agent/pull/869) +- Change casing of docs makefile to Makefile by [@nginx-jack](https://github.com/nginx-jack) in [#884](https://github.com/nginx/agent/pull/884) +- docs: enableGitInfo config and docs-action bump by [@nginx-jack](https://github.com/nginx-jack) in [#886](https://github.com/nginx/agent/pull/886) +- Change go version to latest go 1.23.2 by [@oliveromahony](https://github.com/oliveromahony) in [#889](https://github.com/nginx/agent/pull/889) +- Remove link to github dockerfiles by [@nginx-seanmoloney](https://github.com/nginx-seanmoloney) in [#897](https://github.com/nginx/agent/pull/897) +- Docs: Update link to 3rd party site by [@nginx-aoife](https://github.com/nginx-aoife) in [#898](https://github.com/nginx/agent/pull/898) +- Update the changelog for v2.38 by [@ADubhlaoich](https://github.com/ADubhlaoich) in [#901](https://github.com/nginx/agent/pull/901) + +### 🔨 Maintenance + +We have made the following maintenance-related minor changes: + +- Set log level to debug for inetegration tests by [@aphralG](https://github.com/aphralG) in [#826](https://github.com/nginx/agent/pull/826) +- updated runc dependency highlighted in security scan scan by [@oliveromahony](https://github.com/oliveromahony) in [#842](https://github.com/nginx/agent/pull/842) +- Update CODEOWNERS by [@oCHRISo](https://github.com/oCHRISo) in [#851](https://github.com/nginx/agent/pull/851) +- Check version command output by [@aphralG](https://github.com/aphralG) in [#853](https://github.com/nginx/agent/pull/853) +- Bump NGINX plus go client version from v1 to v2 by [@dhurley](https://github.com/dhurley) in [#879](https://github.com/nginx/agent/pull/879) +- Allowlist Error Messages by [@aphralG](https://github.com/aphralG) in [#907](https://github.com/nginx/agent/pull/907) + --- ## Release [v2.38.0](https://github.com/nginx/agent/releases/tag/v2.38.0) @@ -236,29 +280,3 @@ We have made the following maintenance-related minor changes: - replace duplicate isContainer call by [@oliveromahony](https://github.com/oliveromahony) in [#596](https://github.com/nginx/agent/pull/596) - Add logging to NGINX API http requests by [@dhurley](https://github.com/dhurley) in [#605](https://github.com/nginx/agent/pull/605) ---- -## Release [v2.32.2](https://github.com/nginx/agent/releases/tag/v2.32.2) - -### 🌟 Highlights - -- This release fixes an issue where certain container runtimes were reporting as bare-metal hosts. - -### 🚀 Features - -This release introduces the following new features: - -- feat: improve docker docs by [@Jcahilltorre](https://github.com/Jcahilltorre) in [#587](https://github.com/nginx/agent/pull/587) - -### 🐛 Bug Fixes - -In this release we have resolved the following issues: - -- Fix install-tools by [@Dean-Coakley](https://github.com/Dean-Coakley) in [#581](https://github.com/nginx/agent/pull/581) - -### 📝 Documentation - -We have made the following updates to the documentation: - -- change log updated for last release by [@oliveromahony](https://github.com/oliveromahony) in [#583](https://github.com/nginx/agent/pull/583) -- Restore agent container information from nms docs by [@jputrino](https://github.com/jputrino) in [#584](https://github.com/nginx/agent/pull/584) -- fix: add additional container checks during instance registration by [@mattdesmarais](https://github.com/mattdesmarais) in [#592](https://github.com/nginx/agent/pull/592) diff --git a/site/content/v2/configuration/configuration-overview.md b/site/content/v2/configuration/configuration-overview.md index caafd40991..b5bdd2ef06 100644 --- a/site/content/v2/configuration/configuration-overview.md +++ b/site/content/v2/configuration/configuration-overview.md @@ -1,5 +1,5 @@ --- -title: "Configuration Overview" +title: "How to configure NGINX Agent" draft: false weight: 100 toc: true @@ -9,8 +9,6 @@ categories: ["configuration"] doctypes: ["task"] --- -## Overview - The following sections explain how to configure NGINX Agent using configuration files, CLI flags, and environment variables. {{}} @@ -25,7 +23,7 @@ The following sections explain how to configure NGINX Agent using configuration {{}} -### Configure with Config Files +## Configure with Config Files The default locations of configuration files for NGINX Agent are `/etc/nginx-agent/nginx-agent.conf` and `/var/lib/nginx-agent/agent-dynamic.conf`. The `agent-dynamic.conf` file default location is different for FreeBSD which is located `/var/db/nginx-agent/agent-dynamic.conf`. These files have comments at the top indicating their purpose. @@ -35,7 +33,7 @@ Examples of the configuration files are provided below: example nginx-agent.conf {{}} -In the following example `nginx-agent.conf` file, you can change the `server.host` and `server.grpcPort` to connect to the control/management plane. +In the following example `nginx-agent.conf` file, you can change the `server.host` and `server.grpcPort` to connect to the control plane. {{}} ```nginx {hl_lines=[13]} @@ -44,15 +42,21 @@ In the following example `nginx-agent.conf` file, you can change the `server.hos # # Configuration file for NGINX Agent. # -# This file tracks agent configuration values that are meant to be statically set. There +# This file tracks agent configuration values that are meant to be statically set. There # are additional NGINX Agent configuration values that are set via the API and agent install script -# which can be found in /etc/nginx-agent/agent-dynamic.conf. +# which can be found in /etc/nginx-agent/agent-dynamic.conf. # specify the server grpc port to connect to server: # host of the control plane host: grpcPort: 443 + backoff: # note: default values are prepopulated + initial_interval: 100ms # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + randomization_factor: 0.10 # Add the appropriate float value here, e.g., 0.10 + multiplier: 1.5 # Add the appropriate float value here, e.g., 1.5 + max_interval: 1m # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + max_elapsed_time: 0 # Add the appropriate duration value here, e.g., "0" for indefinite "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour # tls options tls: # enable tls in the nginx-agent setup for grpcs @@ -74,7 +78,7 @@ nginx: # data plane status message / 'heartbeat' dataplane: status: - # poll interval for dataplane status - the frequency the agent will query the dataplane for changes + # poll interval for dataplane status - the frequency the NGINX Agent will query the dataplane for changes poll_interval: 30s # report interval for dataplane status - the maximum duration to wait before syncing dataplane information if no updates have been observed report_interval: 24h @@ -85,6 +89,12 @@ metrics: report_interval: 1m collection_interval: 15s mode: aggregated + backoff: # note: default values are prepopulated + initial_interval: 100ms # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + randomization_factor: 0.10 # Add the appropriate float value here, e.g., 0.10 + multiplier: 1.5 # Add the appropriate float value here, e.g., 1.5 + max_interval: 1m # Add the appropriate duration value here, e.g., "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour + max_elapsed_time: 0 # Add the appropriate duration value here, e.g., "0" for indefinite "100ms" for 100 milliseconds, "5s" for 5 seconds, "1m" for 1 minute, "1h" for 1 hour # OSS NGINX default config path # path to aux file dirs can also be added @@ -125,136 +135,113 @@ Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.con # overwrite the tag values in this file. # # The agent configuration values that API calls can modify are as follows: -# - tags +# tags: +# - dev +# - qa # # The agent configuration value that the agent install script can modify are as follows: -# - instance_group +# instance_group: my-instance-group -instance_group: devenv-group +instance_group: my-instance-group tags: - - devenv - - test + - dev + - qa ``` +## CLI Flags & Environment Variables -### NGINX Agent CLI Flags & Usage {#nginx-agent-cli-flags-usage} +This section details the CLI flags and corresponding environment variables used to configure the NGINX Agent. -This section displays the configurable options for NGINX Agent that can be set with CLI flags. See the CLI flags and their uses in the figure below: +### Usage -
- NGINX Agent CLI flags & usage - -```text -Usage: - nginx-agent [flags] - nginx-agent [command] - -Available Commands: - completion Generate completion script. - help Help about any command - -Flags: - --api-cert string The cert used by the Agent API. - --api-host string The host used by the Agent API. (default "127.0.0.1") - --api-key string The key used by the Agent API. - --api-port int The desired port to use for nginx-agent to expose for HTTP traffic. - --config-dirs string Defines the paths that you want to grant nginx-agent read/write access to. This key is formatted as a string and follows Unix PATH format. (default "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms") - --dataplane-report-interval duration The amount of time the agent will report on the dataplane. After this period of time it will send a snapshot of the dataplane information. (default 24h0m0s) - --dataplane-status-poll-interval duration The frequency the agent will check the dataplane for changes. Used as a "heartbeat" to keep the gRPC connections alive. (default 30s) - --display-name string The instance's 'name' value. - --dynamic-config-path string Defines the path of the Agent dynamic config file. (default "/var/lib/nginx-agent/agent-dynamic.conf") - --features strings A comma-separated list of features enabled for the agent. (default [registration,nginx-config-async,nginx-ssl-config,nginx-counting,metrics,dataplane-status,process-watcher,file-watcher,activity-events,agent-api]) - -h, --help help for nginx-agent - --ignore-directives strings A comma-separated list of ignoring directives which contain sensitive info. - --instance-group string The instance's 'group' value. - --log-level string The desired verbosity level for logging messages from nginx-agent. Available options, in order of severity from highest to lowest, are: panic, fatal, error, info, debug, and trace. (default "info") - --log-path string The path to output log messages to. If the default path doesn't exist, log messages are output to stdout/stderr. - --metrics-bulk-size int The amount of metrics reports collected before sending the data back to the server. (default 20) - --metrics-collection-interval duration Sets the interval, in seconds, at which metrics are collected. (default 15s) - --metrics-mode string Sets the desired metrics collection mode: streaming or aggregation. (default "aggregated") - --metrics-report-interval duration The polling period specified for a single set of metrics being collected. (default 1m0s) - --nginx-config-reload-monitoring-period duration The duration NGINX Agent will monitor error logs after a NGINX reload (default 10s) - --nginx-exclude-logs string One or more NGINX access log paths that you want to exclude from metrics collection. This key is formatted as a string and multiple values should be provided as a comma-separated list. - --nginx-socket string The NGINX Plus counting unix socket location. (default "unix:/var/run/nginx-agent/nginx.sock") - --nginx-treat-warnings-as-errors On nginx -t, treat warnings as failures on configuration application. - --queue-size int The size of the NGINX Agent internal queue. - --server-command string The name of the command server sent in the tls configuration. - --server-grpcport int The desired GRPC port to use for nginx-agent traffic. - --server-host string The IP address of the server host. IPv4 addresses and hostnames are supported. - --server-metrics string The name of the metrics server sent in the tls configuration. - --server-token string An authentication token that grants nginx-agent access to the commander and metrics services. Auto-generated by default. (default "e202f883-54c6-4702-be15-3ba6e507879a") - --tags strings A comma-separated list of tags to add to the current instance or machine, to be used for inventory purposes. - --tls-ca string The path to the CA certificate file to use for TLS. - --tls-cert string The path to the certificate file to use for TLS. - --tls-enable Enables TLS for secure communications. - --tls-key string The path to the certificate key file to use for TLS. - --tls-skip-verify Only intended for demonstration, sets InsecureSkipVerify for gRPC TLS credentials - -v, --version version for nginx-agent - -Use "nginx-agent [command] --help" for more information about a command. +#### CLI Flags + +```sh +nginx-agent [flags] ``` -
+#### Environment Variables + +```sh +export ENV_VARIABLE_NAME="value" +nginx-agent +``` + +### CLI Flags and Environment Variables + +{{< warning >}} + +Before version 2.35.0, the environment variables were prefixed with `NMS_` instead of `NGINX_AGENT_`. + +If you are upgrading from an older version, update your configuration accordingly. + +{{< /warning >}} + +{{}} +| CLI flag | Environment variable | Description | +|---------------------------------------------|--------------------------------------|-----------------------------------------------------------------------------| +| `--api-cert` | `NGINX_AGENT_API_CERT` | Specifies the certificate used by the Agent API. | +| `--api-host` | `NGINX_AGENT_API_HOST` | Sets the host used by the Agent API. Default: *127.0.0.1* | +| `--api-key` | `NGINX_AGENT_API_KEY` | Specifies the key used by the Agent API. | +| `--api-port` | `NGINX_AGENT_API_PORT` | Sets the port for exposing nginx-agent to HTTP traffic. | +| `--config-dirs` | `NGINX_AGENT_CONFIG_DIRS` | Defines directories NGINX Agent can read/write. Default: *"/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms"* | +| `--dataplane-report-interval` | `NGINX_AGENT_DATAPLANE_REPORT_INTERVAL` | Sets the interval for dataplane reporting. Default: *24h0m0s* | +| `--dataplane-status-poll-interval` | `NGINX_AGENT_DATAPLANE_STATUS_POLL_INTERVAL` | Sets the interval for polling dataplane status. Default: *30s* | +| `--display-name` | `NGINX_AGENT_DISPLAY_NAME` | Sets the instance's display name. | +| `--dynamic-config-path` | `NGINX_AGENT_DYNAMIC_CONFIG_PATH` | Specifies the path of the Agent dynamic config file. Default: *"/var/lib/nginx-agent/agent-dynamic.conf"* | +| `--features` | `NGINX_AGENT_FEATURES` | Specifies a comma-separated list of features enabled for the agent. Default: *[registration, nginx-config-async, nginx-ssl-config, nginx-counting, metrics, dataplane-status, process-watcher, file-watcher, activity-events, agent-api]* | +| `--ignore-directives` | | Specifies a comma-separated list of directives to ignore for sensitive info.| +| `--instance-group` | `NGINX_AGENT_INSTANCE_GROUP` | Sets the instance's group value. | +| `--log-level` | `NGINX_AGENT_LOG_LEVEL` | Sets the logging level (e.g., panic, fatal, error, info, debug, trace). Default: *info* | +| `--log-path` | `NGINX_AGENT_LOG_PATH` | Specifies the path to output log messages. | +| `--metrics-bulk-size` | `NGINX_AGENT_METRICS_BULK_SIZE` | Specifies the number of metrics reports collected before sending data. Default: *20* | +| `--metrics-collection-interval` | `NGINX_AGENT_METRICS_COLLECTION_INTERVAL` | Sets the interval for metrics collection. Default: *15s* | +| `--metrics-mode` | `NGINX_AGENT_METRICS_MODE` | Sets the metrics collection mode: streaming or aggregation. Default: *aggregated* | +| `--metrics-report-interval` | `NGINX_AGENT_METRICS_REPORT_INTERVAL` | Sets the interval for reporting collected metrics. Default: *1m0s* | +| `--nginx-config-reload-monitoring-period` | | Sets the duration to monitor error logs after an NGINX reload. Default: *10s* | +| `--nginx-exclude-logs` | `NGINX_AGENT_NGINX_EXCLUDE_LOGS` | Specifies paths of NGINX access logs to exclude from metrics collection. | +| `--nginx-socket` | `NGINX_AGENT_NGINX_SOCKET` | Specifies the location of the NGINX Plus counting Unix socket. Default: *unix:/var/run/nginx-agent/nginx.sock* | +| `--nginx-treat-warnings-as-errors` | `NGINX_AGENT_NGINX_TREAT_WARNINGS_AS_ERRORS` | Treats warnings as failures on configuration application. | +| `--queue-size` | `NGINX_AGENT_QUEUE_SIZE` | Specifies the size of the NGINX Agent internal queue. | +| `--server-command` | | Specifies the name of the command server sent in the TLS configuration. | +| `--server-grpcport` | `NGINX_AGENT_SERVER_GRPCPORT` | Sets the desired GRPC port for NGINX Agent traffic. | +| `--server-host` | `NGINX_AGENT_SERVER_HOST` | Specifies the IP address of the server host. | +| `--server-metrics` | | Specifies the name of the metrics server sent in the TLS configuration. | +| `--server-token` | `NGINX_AGENT_SERVER_TOKEN` | Sets the authentication token for accessing the commander and metrics services. Default: *e202f883-54c6-4702-be15-3ba6e507879a* | +| `--tags` | `NGINX_AGENT_TAGS` | Specifies a comma-separated list of tags for the instance or machine. | +| `--tls-ca` | `NGINX_AGENT_TLS_CA` | Specifies the path to the CA certificate file for TLS. | +| `--tls-cert` | `NGINX_AGENT_TLS_CERT` | Specifies the path to the certificate file for TLS. | +| `--tls-enable` | `NGINX_AGENT_TLS_ENABLE` | Enables TLS for secure communications. | +| `--tls-key` | `NGINX_AGENT_TLS_KEY` | Specifies the path to the certificate key file for TLS. | +| `--tls-skip-verify` | `NGINX_AGENT_TLS_SKIP_VERIFY` | Insecurely skips verification for gRPC TLS credentials. | +{{}} + +
+ +{{}} +Use the `--config-dirs` command-line option, or the `config_dirs` key in the `nginx-agent.conf` file, to identify the directories NGINX Agent can read from or write to. This setting also defines the location to which you can upload config files when using a control plane. -#### NGINX Agent Config Dirs Option +NGINX Agent cannot write to directories outside the specified location when updating a config and cannot upload files to directories outside of the configured location. -Use the `--config-dirs` command-line option, or the `config_dirs` key in the `nginx-agent.conf` file, to identify the directories NGINX Agent can read from or write to. This setting also defines the location to which you can upload config files when using a control/management plane. NGINX Agent cannot write to directories outside the specified location when updating a config and cannot upload files to directories outside of the configured location. NGINX Agent follows NGINX configuration directives to file paths outside the designated directories and reads certificates' metadata. NGINX Agent uses the following directives: - [`ssl_certificate`](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) -#### NGINX Agent Dynamic Config Path Option +{{}} -Use the `--dynamic-config-path` command-line option to set the location of the dynamic config file. This setting also requires you to move your dynamic config to the new path, or create a new dynamic config file at the specified location. +{{}} Use the `--dynamic-config-path` command-line option to set the location of the dynamic config file. This setting also requires you to move your dynamic config to the new path, or create a new dynamic config file at the specified location. Default location in Linux environments: `/var/lib/nginx-agent/agent-dynamic.conf` Default location in FreeBSD environments: `/var/db/nginx-agent/agent-dynamic.conf` -### NGINX Agent Environment Variables - -This section displays the configurable options for NGINX Agent that can be set with environment variables. A list of the configurable environment variables can be seen below: - -
- NGINX Agent Environment Variables - -```text -- NMS_INSTANCE_GROUP -- NMS_DISPLAY_NAME -- NMS_FEATURES -- NMS_LOG_LEVEL -- NMS_LOG_PATH -- NMS_PATH -- NMS_METRICS_COLLECTION_INTERVAL -- NMS_METRICS_MODE -- NMS_METRICS_BULK_SIZE -- NMS_METRICS_REPORT_INTERVAL -- NMS_NGINX_EXCLUDE_LOGS -- NMS_NGINX_SOCKET -- NMS_NGINX_TREAT_WARNINGS_AS_ERRORS -- NMS_SERVER_GRPCPORT -- NMS_SERVER_HOST -- NMS_SERVER_TOKEN -- NMS_SERVER_COMMAND -- NMS_SERVER_METRICS -- NMS_TAGS -- NMS_TLS_CA -- NMS_TLS_CERT -- NMS_TLS_ENABLE -- NMS_TLS_KEY -- NMS_TLS_SKIP_VERIFY -- NMS_CONFIG_DIRS -- NMS_QUEUE_SIZE -- NMS_DATAPLANE_REPORT_INTERVAL -- NMS_DATAPLANE_STATUS_POLL_INTERVAL -``` -
+{{
}} -### NGINX Agent Log Rotation +## Log Rotation -By default, NGINX Agent rotates logs daily using logrotate with the following configuration: +By default, NGINX Agent rotates logs daily using logrotate with the following configuration:
NGINX Agent Logrotate Configuration @@ -275,13 +262,13 @@ By default, NGINX Agent rotates logs daily using logrotate with the following co # old log files are compressed compress # if the log file is missing it will go on to the next one without issuing an error message - missingok + missingok # do not rotate the log if it is empty notifempty } ```
-If you need to make changes to the default configuration you can update the file here `/etc/logrotate.d/nginx-agent` +If you need to change the default configuration, update the file at `/etc/logrotate.d/nginx-agent`. -For more detail on logrotate configuration see [Logrotate Configuration Options](https://linux.die.net/man/8/logrotate) +For more details on logrotate configuration, see [Logrotate Configuration Options](https://linux.die.net/man/8/logrotate). \ No newline at end of file diff --git a/site/content/v2/configuration/configure-nginx-agent-group.md b/site/content/v2/configuration/configure-nginx-agent-group.md index 43cd80bde1..45c3e9094c 100644 --- a/site/content/v2/configuration/configure-nginx-agent-group.md +++ b/site/content/v2/configuration/configure-nginx-agent-group.md @@ -1,5 +1,5 @@ --- -title: "Add NGINX Users to nginx-agent Group" +title: "Add NGINX users to nginx-agent group" draft: false weight: 300 toc: true diff --git a/site/content/v2/configuration/encrypt-communication.md b/site/content/v2/configuration/encrypt-communication.md index 26d0b015f0..7d9f1b5472 100644 --- a/site/content/v2/configuration/encrypt-communication.md +++ b/site/content/v2/configuration/encrypt-communication.md @@ -1,5 +1,5 @@ --- -title: Encrypt Communication +title: Encrypt communication tags: - docs toc: true @@ -13,7 +13,7 @@ Follow the steps in this guide to encrypt communication between NGINX Agent and ## Before You Begin -To enable mTLS, you must have TLS enabled and supply a key, cert, and a CA cert on both the client and server. TSee the [Secure Traffic with Certificates](https://docs.nginx.com/nginx-management-suite/admin-guides/configuration/secure-traffic/) topic for instructions on how to generate keys and set them in the specific values in the NGINX Agent configuration. +To enable mTLS, you must have TLS enabled and supply a key, cert, and a CA cert on both the client and server. See the [Secure Traffic with Certificates](https://docs.nginx.com/nginx-instance-manager/system-configuration/secure-traffic/) topic for instructions on how to generate keys and set them in the specific values in the NGINX Agent configuration. ## Enabling mTLS @@ -50,10 +50,10 @@ nginx-agent --tls-cert "path-to-cert" --tls-key "path-to-key" --tls-ca "path-to- To enable mTLS for NGINX Agent using environment variables, run the following commands: ```bash -NMS_TLS_CA="my-env-ca" -NMS_TLS_KEY="my-env-key" -NMS_TLS_CERT="my-env-cert" -NMS_TLS_ENABLE=true +NGINX_AGENT_TLS_CA="my-env-ca" +NGINX_AGENT_TLS_KEY="my-env-key" +NGINX_AGENT_TLS_CERT="my-env-cert" +NGINX_AGENT_TLS_ENABLE=true ```
@@ -87,7 +87,7 @@ nginx-agent --tls-enable To enable server-side TLS using environment variables, run the following commands: ```bash -NMS_TLS_ENABLE=true +NGINX_AGENT_TLS_ENABLE=true ```
@@ -110,7 +110,7 @@ tls: To enable insecure mode, you simply need to set `tls:enable` to `false`. Setting this value to `false` can be done only by updating the configuration file or with environment variables. See the following examples: -### Enabling Insecure Mode via Config Values** +### Enabling Insecure Mode via Config Values You can edit the `/etc/nginx-agent/nginx-agent.conf` file to enable insecure mode. Make the following changes: @@ -119,10 +119,10 @@ tls: enable: false ``` -### Enabling Insecure Mode with Environment Variables** +### Enabling Insecure Mode with Environment Variables To enable insecure mode using environment variables, run the following commands: ```bash -NMS_TLS_ENABLE=false +NGINX_AGENT_TLS_ENABLE=false ``` diff --git a/site/content/v2/configuration/health-checks.md b/site/content/v2/configuration/health-checks.md new file mode 100644 index 0000000000..f045955fbd --- /dev/null +++ b/site/content/v2/configuration/health-checks.md @@ -0,0 +1,62 @@ +--- +title: "Health checks" +draft: false +weight: 400 +toc: true +tags: [ "docs" ] +categories: ["configuration"] +doctypes: ["task"] +--- + +## Overview + +The REST API includes a health endpoint to verify the status of NGINX Agent. + +## Configure the REST API + +To enable the REST API, add the following configuration to the NGINX Agent configuration file, `/etc/nginx-agent/nginx-agent.conf`: + +```nginx +api: + host: 127.0.0.1 + port: 8038 +``` + +## Using health checks + +After you enable the REST API, calling the `/health` endpoint returns the following JSON response: + +```json +{ + "status": "OK", + "checks": [ + { + "name": "registration", + "status": "OK" + }, + { + "name": "commandConnection", + "status": "OK" + }, + { + "name": "metricsConnection", + "status": "OK" + } + ] +} +``` + +The top-level `status` field is the overall health status of NGINX Agent. The health status can return three different states: + +1. `PENDING`: NGINX Agent is still determining its health status. +2. `OK`: NGINX Agent is in a healthy state. +3. `ERROR`: NGINX Agent is in an unhealthy state. + +The health checkpoint performs three checks to determine the overall health of the NGINX Agent: + +1. `registration`: Checks if NGINX Agent has successfully registered with the management plane server. +2. `commandConnection`: Checks if NGINX Agent is still able to receive and send commands. +3. `metricsConnection`: Checks if NGINX Agent is still able to send metric reports. + +If any of the checks are in an `ERROR` status, then the overall status of NGINX Agent will change to `ERROR` as well. + diff --git a/site/content/v2/installation-upgrade/_index.md b/site/content/v2/installation-upgrade/_index.md index 9419e71857..4c3d498997 100644 --- a/site/content/v2/installation-upgrade/_index.md +++ b/site/content/v2/installation-upgrade/_index.md @@ -1,7 +1,6 @@ --- -title: "Installation and Upgrade" +title: "Installation and upgrade" +description: "Learn how to install, upgrade, and uninstall NGINX Agent." menu: docs weight: 300 ---- - -Learn how to install, upgrade, and uninstall NGINX Agent. \ No newline at end of file +--- \ No newline at end of file diff --git a/site/content/v2/installation-upgrade/container-environments/_index.md b/site/content/v2/installation-upgrade/container-environments/_index.md index 939ba9d18e..ca964e34b0 100644 --- a/site/content/v2/installation-upgrade/container-environments/_index.md +++ b/site/content/v2/installation-upgrade/container-environments/_index.md @@ -1,6 +1,6 @@ --- -title: "Container Environments" +title: "Container environments" +description: "Learn how to build and run NGINX Agent docker images." +menu: docs weight: 800 ---- - -Learn how to build and run NGINX Agent docker images. \ No newline at end of file +--- \ No newline at end of file diff --git a/site/content/v2/installation-upgrade/container-environments/docker-images.md b/site/content/v2/installation-upgrade/container-environments/docker-images.md index 749bb7128d..40b3a3b2f8 100644 --- a/site/content/v2/installation-upgrade/container-environments/docker-images.md +++ b/site/content/v2/installation-upgrade/container-environments/docker-images.md @@ -1,5 +1,5 @@ --- -title: "Build Container Images" +title: "Build container images" draft: false weight: 100 toc: true @@ -11,12 +11,17 @@ docs: "DOCS-1410" ## Overview -NGINX Agent is a companion daemon for NGINX Open Source or NGINX Plus instances and must run in the same container to work. The NGINX Agent GitHub repository includes [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) that you can use to build custom container images that bundle NGINX Agent with NGINX or NGINX Plus. +NGINX Agent is a companion daemon for NGINX Open Source or NGINX Plus instances and must run in the same container to work. This document explains multiple ways in which NGINX Agent can be run alongside NGINX in a container. If you want to use NGINX Agent with NGINX Plus, you need to purchase an NGINX Plus license. Contact your F5 Sales representative for assistance. See the requirements and supported operating systems in the [NGINX Agent Technical Specifications]({{< relref "technical-specifications.md" >}}) topic. +## Deploy Offical NGINX and NGINX Plus Containers + +Docker images are available in the [Deploying NGINX and NGINX Plus on Docker](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/) NGINX documentation. + +This guide provides instructions on how to build images with NGINX Agent and NGINX packaged together. It includes steps for downloading the necessary Docker images, configuring your Docker environment, and deploying NGINX and NGINX Plus containers. ## Set up your environment @@ -72,16 +77,6 @@ git clone git@github.com:nginx/agent.git {{% /tabs %}} -### Download the agent binary {#agent-binary} - -Before you can build a container image with NGINX, you must build or download the **agent** binary. - -The **agent** binary packages are available from the [NGINX Agent Releases](https://github.com/nginx/agent/releases) page on GitHub. - -Download the binary package for the operating system that you will use in the container image. - -Note the location and name of the downloaded package. You will need to use this when running the **make** command to build the image (referred to as `[PATH-TO-PACKAGE]` in the example commands below). - ### Download the NGINX Plus certificate and key {#myf5-download} {{< fa "circle-info" "text-muted" >}} **This step is required if you are using NGINX Plus. If you are using NGINX open source, you can skip this section.** @@ -105,72 +100,28 @@ In order to build a container image with NGINX Plus, you must provide the SSL ce - Be sure to replace the example certificate and key filenames shown in the example command with your actual file names. - The file names in the *build/certs* directory must match those shown in the example. -## Build the official NGINX Agent image with Docker - -{{}} - -{{%tab name="NGINX Open Source"%}} +## Run the NGINX Agent container -Change to the directory where the Dockerfile is located: +To run NGINX Agent container using Docker use the following command: ```shell -$ cd scripts/docker/official/nginx-oss-with-nginx-agent/alpine/ +docker pull docker-registry.nginx.com/nginx/agent:mainline ``` - -- To build an image that contains the latest NGINX Agent and the latest mainline version of NGINX run the following command: - - ```shell - $ docker build -t nginx-agent . --no-cache -f ./Dockerfile.mainline - ``` - -- To build an image that contains the latest NGINX Agent and the latest stable version of NGINX run the following command: - - ```shell - $ docker build -t nginx-agent . --no-cache -f ./Dockerfile.stable - ``` - -{{% /tab %}} - -{{%tab name="NGINX Plus"%}} - -1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5) and download your "nginx-repo.crt" and "nginx-repo.key" files. These files are also provided with the NGINX Plus trial package. - -1. Copy the files to the directory where the Dockerfile is located **scripts/docker/official/nginx-plus-with-nginx-agent/alpine/**. - -1. To build an image that contains the latest NGINX Agent and the latest version of NGINX Plus change to the directory where the Dockerfile is located: - ```shell -$ cd scripts/docker/official/nginx-plus-with-nginx-agent/alpine/ +docker tag docker-registry.nginx.com/nginx/agent:mainline nginx-agent ``` - -1. Run the following command to build the image: - ```shell -$ docker build -t nginx-agent . \ - --no-cache -f ./Dockerfile \ - --secret id=nginx-crt,src=nginx-repo.crt \ - --secret id=nginx-key,src=nginx-repo.key -``` -{{% /tab %}} -{{% /tabs %}} - - -## Run the NGINX Agent container - -Here is an example of how to run the NGINX Agent container using Docker: - -```console docker run --name nginx-agent -d nginx-agent ``` -{{}}To learn more about the configuration options, refer to the NGINX Agent [Configuration Overview]({{< relref "/how-to/configuration-overview.md" >}}).{{}} +{{}}To learn more about the configuration options, refer to the NGINX Agent [Configuration Overview]({{< relref "/v2/configuration/configuration-overview" >}}).{{}} ### Enable the gRPC interface To connect your NGINX Agent container to your NGINX One or NGINX Instance Manager instance, you must enable the gRPC interface. To do this, you must edit the NGINX Agent configuration file, *nginx-agent.conf*. For example: ```yaml -erver: +server: host: 127.0.0.1 # mock control plane host grpcPort: 54789 # mock control plane gRPC port @@ -199,6 +150,20 @@ docker run --name nginx-agent -d \ nginx-agent ``` +To ensure that the REST Interface is correctly configured, you can use the `curl` command targeting the following endpoint from your terminal: + +```shell +curl 0.0.0.0:8038/nginx/ +``` + +If the REST Interface is configured correctly, then you should see a JSON object ouputted to the terminal containing metadata such as NGINX version, path to the NGINX conf, and runtime modules. + +**Sample Output:** + +```code +[{"nginx_id":"b636d4376dea15405589692d3c5d3869ff3a9b26b0e7bb4bb1aa7e658ace1437","version":"1.27.1","conf_path":"/etc/nginx/nginx.conf","process_id":"7","process_path":"/usr/sbin/nginx","start_time":1725878806000,"built_from_source":false,"loadable_modules":null,"runtime_modules":["http_addition_module","http_auth_request_module","http_dav_module","http_flv_module","http_gunzip_module","http_gzip_static_module","http_mp4_module","http_random_index_module","http_realip_module","http_secure_link_module","http_slice_module","http_ssl_module","http_stub_status_module","http_sub_module","http_v2_module","http_v3_module","mail_ssl_module","stream_realip_module","stream_ssl_module","stream_ssl_preread_module"],"plus":{"enabled":false,"release":""},"ssl":{"ssl_type":0,"details":["OpenSSL","3.3.0","9 Apr 2024 (running with OpenSSL 3.3.1 4 Jun 2024)"]},"status_url":"","configure_args":["","prefix=/etc/nginx","sbin-path=/usr/sbin/nginx","modules-path=/usr/lib/nginx/modules","conf-path=/etc/nginx/nginx.conf","error-log-path=/var/log/nginx/error.log","http-log-path=/var/log/nginx/access.log","pid-path=/var/run/nginx.pid","lock-path=/var/run/nginx.lock","http-client-body-temp-path=/var/cache/nginx/client_temp","http-proxy-temp-path=/var/cache/nginx/proxy_temp","http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp","http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp","http-scgi-temp-path=/var/cache/nginx/scgi_temp","with-perl_modules_path=/usr/lib/perl5/vendor_perl","user=nginx","group=nginx","with-compat","with-file-aio","with-threads","with-http_addition_module","with-http_auth_request_module","with-http_dav_module","with-http_flv_module","with-http_gunzip_module","with-http_gzip_static_module","with-http_mp4_module","with-http_random_index_module","with-http_realip_module","with-http_secure_link_module","with-http_slice_module","with-http_ssl_module","with-http_stub_status_module","with-http_sub_module","with-http_v2_module","with-http_v3_module","with-mail","with-mail_ssl_module","with-stream","with-stream_realip_module","with-stream_ssl_module","with-stream_ssl_preread_module","with-cc-opt='-Os -fstack-clash-protection -Wformat -Werror=format-security -g'","with-ld-opt=-Wl,--as-needed,-O1,--sort-common"],"error_log_paths":null}] +``` +
## Build the NGINX Agent images for specific OS targets @@ -207,175 +172,49 @@ docker run --name nginx-agent -d \ The NGINX Agent GitHub repo has a set of Make commands that you can use to build a container image for an specific operating system and version: -- `make official-oss-image` builds an image containing NGINX Agent and NGINX open source. -- `make official-plus-image` builds an image containing NGINX Agent and NGINX Plus. +- `make oss-image` builds an image containing NGINX Agent and NGINX open source. +- `make image` builds an image containing NGINX Agent and NGINX Plus. You can pass the following arguments when running the **make** command to build an NGINX Agent container image. {{}} | Argument | Definition | | ---------------- | -------------------------| -| PACKAGE_NAME | **Required.** The full path to the downloaded [agent binary package](#agent-binary).
Must precede the **make** command. | | OS_RELEASE | The Linux distribution to use as the base image.
Can also be set in the repo Makefile.| | OS_VERSION | The version of the Linux distribution to use as the base image.
Can also be set in the repo Makefile.| -{{
}} - -Refer to the [Supported distributions](technical-specifications.md/#supported-distributions) table to find out which base images you can use. -You can find the official images and versions for each distribution on [Docker Hub](https://hub.docker.com/search?image_filter=official&q=&type=image). +| AGENT_VERSION | The versions of NGINX agent that you want installed on the image.| -Keep the following information in mind when using the NGINX Agent [Dockerfiles](https://github.com/nginx/agent/tree/main/scripts/docker) to build container images: - -- On some operating systems, you need root privileges (**sudo**) to run **make** commands. -- If you choose to run the **docker build** or **podman build** command instead of using the **make** commands provided, you must do so from the nginx-agent repository's root directory. +{{
}} ### Build NGINX open source images -Run the following **make** command to build the default image, which uses Alpine 3.19 as the base image. - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] make official-oss-image -``` - -### Example build commands by distribution - -{{}} - -{{%tab name="alma linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=almalinux make oss-image -``` - -{{% /tab %}} - -{{%tab name="alpine linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=alpine make oss-image -``` - -{{% /tab %}} - -{{%tab name="amazon linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=amazonlinux make oss-image -``` - -{{% /tab %}} - -{{%tab name="debian"%}} +Run the following `make` command to build the default image, which uses Alpine as the base image: ```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=debian make oss-image +IMAGE_BUILD_TARGET=install-agent-repo make oss-image ``` -{{% /tab %}} - -{{%tab name="oracle linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=oraclelinux make oss-image -``` - -{{% /tab %}} - -{{%tab name="rocky linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=rockylinux make oss-image -``` - -{{% /tab %}} - -{{%tab name="ubuntu"%}} - -The command below creates a base image using the most recent LTS version of Ubuntu as the base image: +To build an image with Debian and an older version of NGINX Agent you can run the following command: ```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] make oss-image OS_RELEASE=ubuntu +IMAGE_BUILD_TARGET=install-agent-repo NGINX_AGENT_VERSION=2.37.0~bullseye OS_RELEASE=debian OS_VERSION=bullseye-slim make oss-image ``` -{{% /tab %}} - -{{% /tabs %}} - ### Build NGINX Plus images {{}}You need a license to use NGINX Agent with NGINX Plus. You must complete the steps in the [Download the certificate and key files from MyF5](#myf5-download) section before proceeding.{{}} -Run the following `make` command to build the default image, which uses Ubuntu 22.04 (Jammy) as the base image. - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] make official-plus-image -``` - -### Example NGINX Plus build commands by distribution - -{{}} - -{{%tab name="alpine linux"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=alpine make official-plus-image -``` - -{{% /tab %}} - -{{%tab name="amazon linux"%}} +Run the following `make` command to build the default image, which uses Ubuntu 24.04 (Noble) as the base image. ```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=amazonlinux make official-plus-image +IMAGE_BUILD_TARGET=install-agent-repo make image ``` -{{% /tab %}} - -{{%tab name="centos"%}} +To build an image with Debian and an older version of NGINX Agent you can run the following command: ```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=centos OS_VERSION=7 make official-plus-image +IMAGE_BUILD_TARGET=install-agent-repo NGINX_AGENT_VERSION=2.37.0~bullseye OS_RELEASE=debian OS_VERSION=bullseye-slim make image ``` -{{% /tab %}} - -{{%tab name="debian"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=debian OS_VERSION=bullseye-slim make official-plus-image -``` - -{{% /tab %}} -{{%tab name="oracle linux"%}} -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=oraclelinux make official-plus-image -``` - -{{% /tab %}} - -{{%tab name="rhel"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=redhatenterprise make official-plus-image -``` - -{{% /tab %}} - -{{%tab name="suse"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=suse OS_VERSION=sle15 make official-plus-image -``` - -{{% /tab %}} - -{{%tab name="ubuntu"%}} - -```shell -PACKAGE_NAME=[PATH-TO-PACKAGE] OS_RELEASE=ubuntu make official-plus-image -``` - -{{% /tab %}} - -{{% /tabs %}} diff --git a/site/content/v2/installation-upgrade/container-environments/docker-support.md b/site/content/v2/installation-upgrade/container-environments/docker-support.md index 7736fa9512..b0bdd98a65 100644 --- a/site/content/v2/installation-upgrade/container-environments/docker-support.md +++ b/site/content/v2/installation-upgrade/container-environments/docker-support.md @@ -1,5 +1,5 @@ --- -title: Container Support and Troubleshooting +title: Container support and troubleshooting categories: - installation draft: false @@ -24,8 +24,8 @@ To collect metrics about the Docker container that the NGINX Agent is running in NGINX Agent supports both versions of cgroups. -- https://www.kernel.org/doc/Documentation/cgroup-v1/ -- https://www.kernel.org/doc/Documentation/cgroup-v2.txt +- https://www.kernel.org/doc/Documentation/cgroup-v1/ +- https://www.kernel.org/doc/Documentation/cgroup-v2.txt ## Metrics diff --git a/site/content/v2/installation-upgrade/getting-started.md b/site/content/v2/installation-upgrade/getting-started.md index 541d43299b..578037f537 100644 --- a/site/content/v2/installation-upgrade/getting-started.md +++ b/site/content/v2/installation-upgrade/getting-started.md @@ -1,5 +1,5 @@ --- -title: "Getting Started" +title: "Getting started" draft: false weight: 100 toc: true @@ -15,7 +15,7 @@ Follow these steps to configure and run NGINX Agent and a mock interface ("contr ## Install NGINX -Follow the steps in the [Installation]({{< ref "/v2/installation-upgrade/installation-github.md" >}}) section to download, install, and run NGINX. +Follow the steps in the [Installation](https://docs.nginx.com/nginx/admin-guide/installing-nginx/) section to download, install, and run NGINX. ## Clone the NGINX Agent Repository @@ -23,7 +23,7 @@ Using your preferred method, clone the NGINX Agent repository into your developm ## Install Go -NGINX Agent and the Mock Control Plane are written in Go. Go 1.23.0 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/). +NGINX Agent and the Mock Control Plane are written in Go. Go 1.23 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/). ## Start the gRPC Mock Control Plane @@ -94,7 +94,7 @@ The mock control plane can use either gRPC or REST protocols to communicate with ## Launch Swagger UI -Swagger UI requires goswagger be installed. See [instructions for installing goswagger](https://goswagger.io/install.html) for additional help. +Swagger UI requires goswagger be installed. See [instructions for installing goswagger](https://goswagger.io/go-swagger/install/) for additional help. To launch the Swagger UI for the REST interface run the following command: @@ -177,5 +177,5 @@ NGINX Agent uses formatted log files to collect metrics. Expanding log formats a {{< important >}} Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services. -For more information, see [NGINX Agent Log Rotation]({{< relref "/how-to/configuration-overview.md#nginx-agent-log-rotation" >}}). -{{< /important >}} \ No newline at end of file +For more information, see [NGINX Agent Log Rotation]({{< relref "/v2/configuration/configuration-overview.md#nginx-agent-log-rotation" >}}). +{{< /important >}} diff --git a/site/content/v2/installation-upgrade/installation-github.md b/site/content/v2/installation-upgrade/installation-github.md index ba507c7594..d53a07006e 100644 --- a/site/content/v2/installation-upgrade/installation-github.md +++ b/site/content/v2/installation-upgrade/installation-github.md @@ -1,5 +1,5 @@ --- -title: "Installation From GitHub Release" +title: "Installation from GitHub release" draft: false weight: 200 toc: true @@ -30,7 +30,7 @@ Use your system's package manager to install the package. Some examples: ``` - RHEL, CentOS RHEL, Amazon Linux, Oracle Linux, and other distributions using the `yum` package manager - + ```shell sudo yum localinstall nginx-agent-.rpm ``` @@ -48,7 +48,7 @@ Use your system's package manager to install the package. Some examples: ``` - FreeBSD - + ```shell sudo pkg add nginx-agent-.pkg ``` diff --git a/site/content/v2/installation-upgrade/installation-oss.md b/site/content/v2/installation-upgrade/installation-oss.md index 9444700f6f..5e82dd21b1 100644 --- a/site/content/v2/installation-upgrade/installation-oss.md +++ b/site/content/v2/installation-upgrade/installation-oss.md @@ -1,5 +1,5 @@ --- -title: "Installation From NGINX Repository" +title: "Installation from NGINX repository" draft: false weight: 300 toc: true @@ -16,7 +16,7 @@ Learn how to install NGINX Agent from the NGINX Open Source repository. ## Prerequisites - NGINX installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/) -- A [supported operating system and architecture](../technical-specifications/#supported-distributions) +- A [supported operating system and architecture]({{< relref "/technical-specifications.md#supported-distributions" >}}) - `root` privilege ## Configure NGINX OSS Repository for installing NGINX Agent @@ -28,7 +28,8 @@ Before you install NGINX Agent for the first time on your system, you need to se - [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian) - [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles) - [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux) -- [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux) +- [Installing NGINX Agent on Amazon Linux 2](#installing-nginx-agent-on-amazon-linux-2) +- [Installing NGINX Agent on Amazon Linux 2023](#installing-nginx-agent-on-amazon-linux-2023) - [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd) ### Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux @@ -57,7 +58,7 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo yum install nginx-agent ``` - When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + When prompted to accept the GPG key, verify that the fingerprint matches `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3`, and if so, accept it. ### Installing NGINX Agent on Ubuntu @@ -80,12 +81,20 @@ Before you install NGINX Agent for the first time on your system, you need to se gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg ``` - The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + The output should contain the full fingerprints `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3` as follows: ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 - uid nginx signing key + pub rsa4096 2024-05-29 [SC] + 8540A6F18833A80E9C1653A42FD21310B49F6B46 + uid nginx signing key + + pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + + pub rsa4096 2024-05-29 [SC] + 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3 + uid nginx signing key ``` {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} @@ -134,12 +143,20 @@ Before you install NGINX Agent for the first time on your system, you need to se --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg ``` - The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + The output should contain the full fingerprints `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3` as follows: ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 - uid nginx signing key + pub rsa4096 2024-05-29 [SC] + 8540A6F18833A80E9C1653A42FD21310B49F6B46 + uid nginx signing key + + pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + + pub rsa4096 2024-05-29 [SC] + 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3 + uid nginx signing key ``` {{< important >}}If the fingerprint is different, remove the file.{{< /important >}} @@ -174,7 +191,7 @@ Before you install NGINX Agent for the first time on your system, you need to se ``` 1. To set up the zypper repository for `nginx-agent` packages, run the following command: - + ```shell sudo zypper addrepo --gpgcheck --refresh --check \ 'http://packages.nginx.org/nginx-agent/sles/$releasever_major' nginx-agent @@ -192,12 +209,20 @@ Before you install NGINX Agent for the first time on your system, you need to se gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key ``` -1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: +1. The output should contain the full fingerprints `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3` as follows: ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 - uid nginx signing key + pub rsa4096 2024-05-29 [SC] + 8540A6F18833A80E9C1653A42FD21310B49F6B46 + uid nginx signing key + + pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + + pub rsa4096 2024-05-29 [SC] + 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3 + uid nginx signing key ``` 1. Finally, import the key to the rpm database: @@ -249,7 +274,7 @@ Before you install NGINX Agent for the first time on your system, you need to se ``` The output should contain the following modulus: - + ``` Public-Key: (2048 bit) Modulus: @@ -292,7 +317,43 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo nginx-agent -v ``` -### Installing NGINX Agent on Amazon Linux +### Installing NGINX Agent on Amazon Linux 2023 + +1. Install the prerequisites: + + ```shell + sudo dnf install yum-utils procps-ng + ``` + +1. To set up the dnf repository for Amazon Linux 2023, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: + ``` + [nginx-agent] + name=nginx agent repo + baseurl=https://packages.nginx.org/nginx-agent/amzn/2023/$basearch/ + gpgcheck=1 + enabled=1 + gpgkey=https://nginx.org/keys/nginx_signing.key + module_hotfixes=true + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo dnf install nginx-agent + ``` + +1. When prompted to accept the GPG key, verify that the fingerprint matches + `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, + `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, + `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3` + and if so, accept it. + +1. Verify the installation: + + ```shell + sudo nginx-agent -v + ``` +### Installing NGINX Agent on Amazon Linux 2 1. Install the prerequisites: @@ -317,7 +378,7 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo yum install nginx-agent ``` -1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. +1. When prompted to accept the GPG key, verify that the fingerprint matches `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3`, and if so, accept it. 1. Verify the installation: diff --git a/site/content/v2/installation-upgrade/installation-plus.md b/site/content/v2/installation-upgrade/installation-plus.md index 0600eaeb1f..ba42502106 100644 --- a/site/content/v2/installation-upgrade/installation-plus.md +++ b/site/content/v2/installation-upgrade/installation-plus.md @@ -1,5 +1,5 @@ --- -title: "Installation From NGINX Plus Repository" +title: "Installation from NGINX Plus repository" draft: false weight: 400 toc: true @@ -17,7 +17,7 @@ Learn how to install NGINX Agent from NGINX Plus repository - An NGINX Plus subscription (purchased or trial) - NGINX Plus installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/) -- A [supported operating system and architecture](../technical-specifications/#supported-distributions) +- A [supported operating system and architecture]({{< relref "/technical-specifications.md#supported-distributions" >}}) - `root` privilege - Your credentials to the MyF5 Customer Portal, provided by email from F5, Inc. - Your NGINX Plus certificate and public key (`nginx-repo.crt` and `nginx-repo.key` files), provided by email from F5, Inc. @@ -31,6 +31,7 @@ Before you install NGINX Agent for the first time on your system, you need to se - [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian) - [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles) - [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux) +- [Installing NGINX Agent on Amazon Linux 2023](#installing-nginx-agent-on-amazon-linux-2023) - [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux) - [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd) @@ -80,7 +81,7 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo yum install nginx-agent ``` - When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + When prompted to accept the GPG key, verify that the fingerprint matches `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3`, and if so, accept it. 1. Verify the installation: @@ -244,12 +245,20 @@ Before you install NGINX Agent for the first time on your system, you need to se gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key ``` -1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: +1. The output should contain the full fingerprints `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3` as follows: ``` - pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] - 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 - uid nginx signing key + pub rsa4096 2024-05-29 [SC] + 8540A6F18833A80E9C1653A42FD21310B49F6B46 + uid nginx signing key + + pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24] + 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 + uid nginx signing key + + pub rsa4096 2024-05-29 [SC] + 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3 + uid nginx signing key ``` 1. Finally, import the key to the rpm database: @@ -353,7 +362,55 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo nginx-agent -v ``` -### Installing NGINX Agent on Amazon Linux +### Installing NGINX Agent on Amazon Linux 2023 + +1. Create the `/etc/ssl/nginx` directory: + + ```shell + sudo mkdir -p /etc/ssl/nginx + ``` + +1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files. + +1. Copy the `nginx-repo.crt` and `nginx-repo.key` files to the `/etc/ssl/nginx/` directory: + + ```shell + sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/ + ``` + +1. Install the prerequisites: + + ```shell + sudo dnf install yum-utils procps-ng ca-certificates + ``` + +1. To set up the dnf repository for Amazon Linux 2023, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents: + + ``` + [nginx-agent] + name=nginx-agent repo + baseurl=https://packages.nginx.org/nginx-agent/amzn/2023/$basearch/ + sslclientcert=/etc/ssl/nginx/nginx-repo.crt + sslclientkey=/etc/ssl/nginx/nginx-repo.key + gpgcheck=0 + enabled=1 + ``` + +1. To install `nginx-agent`, run the following command: + + ```shell + sudo dnf install nginx-agent + ``` + +1. When prompted to accept the GPG key, verify that the fingerprint matches `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3`, and if so, accept it. + +1. Verify the installation: + + ```shell + sudo nginx-agent -v + ``` + +### Installing NGINX Agent on Amazon Linux 2 1. Create the `/etc/ssl/nginx` directory: @@ -380,7 +437,7 @@ Before you install NGINX Agent for the first time on your system, you need to se ``` [nginx-agent] name=nginx-agent repo - baseurl=https://pkgs.nginx.com/nginx-agent/amzn2/$releasever/$basearch + baseurl=https://pkgs.nginx.com/nginx-agent/amzn/2023/$releasever/$basearch sslclientcert=/etc/ssl/nginx/nginx-repo.crt sslclientkey=/etc/ssl/nginx/nginx-repo.key gpgcheck=0 @@ -393,7 +450,7 @@ Before you install NGINX Agent for the first time on your system, you need to se sudo yum install nginx-agent ``` -1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. +1. When prompted to accept the GPG key, verify that the fingerprint matches `8540 A6F1 8833 A80E 9C16 53A4 2FD2 1310 B49F 6B46`, `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, `9E9B E90E ACBC DE69 FE9B 204C BCDC D8A3 8D88 A2B3`, and if so, accept it. 1. Verify the installation: diff --git a/site/content/v2/installation-upgrade/uninstall.md b/site/content/v2/installation-upgrade/uninstall.md index c5076775a6..49184df826 100644 --- a/site/content/v2/installation-upgrade/uninstall.md +++ b/site/content/v2/installation-upgrade/uninstall.md @@ -1,5 +1,5 @@ --- -title: "Uninstall NGINX Agent Package" +title: "Uninstall NGINX Agent package" draft: false weight: 700 toc: true @@ -96,7 +96,7 @@ Complete the following steps on each host where you've installed NGINX Agent: ```bash sudo zypper remove nginx-agent - ``` + ``` ### Uninstalling NGINX Agent on Alpine Linux @@ -112,9 +112,9 @@ Complete the following steps on each host where you've installed NGINX agent: ```bash sudo apk del nginx-agent - ``` + ``` -### Uninstalling NGINX Agent on Amazon Linux +### Uninstalling NGINX Agent on Amazon Linux 2 Complete the following steps on each host where you've installed NGINX agent: @@ -128,10 +128,25 @@ Complete the following steps on each host where you've installed NGINX agent: ```bash sudo yum remove nginx-agent - ``` + ``` + +### Uninstalling NGINX Agent on Amazon Linux 2023 + +Complete the following steps on each host where you've installed NGINX agent: + +1. Stop NGINX agent: + + ```bash + sudo systemctl stop nginx-agent + ``` + +2. To uninstall NGINX agent, run the following command: + ```bash + sudo dnf remove nginx-agent + ``` ### Uninstalling NGINX Agent on FreeBSD - + Complete the following steps on each host where you've installed NGINX agent: 1. Stop NGINX agent: @@ -144,4 +159,4 @@ Complete the following steps on each host where you've installed NGINX agent: ```bash sudo pkg delete nginx-agent - ``` + ``` diff --git a/site/content/v2/installation-upgrade/upgrade.md b/site/content/v2/installation-upgrade/upgrade.md index bf5bb90c49..f5e3409af7 100644 --- a/site/content/v2/installation-upgrade/upgrade.md +++ b/site/content/v2/installation-upgrade/upgrade.md @@ -1,5 +1,5 @@ --- -title: "Upgrade NGINX Agent Package" +title: "Upgrade NGINX Agent package" draft: false weight: 600 toc: true diff --git a/site/go.mod b/site/go.mod index 1675cfcc8c..e6c32c9f66 100644 --- a/site/go.mod +++ b/site/go.mod @@ -2,4 +2,4 @@ module github.com/nginx/agent/site go 1.18 -require github.com/nginxinc/nginx-hugo-theme v0.40.8 // indirect +require github.com/nginxinc/nginx-hugo-theme v0.41.23 // indirect diff --git a/site/go.sum b/site/go.sum index bd8c870ccb..3e619b076d 100644 --- a/site/go.sum +++ b/site/go.sum @@ -10,3 +10,5 @@ github.com/nginxinc/nginx-hugo-theme v0.35.0 h1:7XB2GMy6qeJgKEJy9wOS3SYKYpfvLW3/ github.com/nginxinc/nginx-hugo-theme v0.35.0/go.mod h1:DPNgSS5QYxkjH/BfH4uPDiTfODqWJ50NKZdorguom8M= github.com/nginxinc/nginx-hugo-theme v0.40.8 h1:VtoSAtf9k67tI2jzbLRo0oFBAMHZBUPRh/xV4MYullI= github.com/nginxinc/nginx-hugo-theme v0.40.8/go.mod h1:DPNgSS5QYxkjH/BfH4uPDiTfODqWJ50NKZdorguom8M= +github.com/nginxinc/nginx-hugo-theme v0.41.23 h1:ddIfLF7BFd78qyIn3z5aReeC4BO/m9FH81d5S+al/6s= +github.com/nginxinc/nginx-hugo-theme v0.41.23/go.mod h1:DPNgSS5QYxkjH/BfH4uPDiTfODqWJ50NKZdorguom8M= diff --git a/site/layouts/agent-v2-migration/list.html b/site/layouts/agent-v2-migration/list.html new file mode 100644 index 0000000000..54b0b0f66b --- /dev/null +++ b/site/layouts/agent-v2-migration/list.html @@ -0,0 +1,10 @@ +{{ define "main" }} +
+ +
+ {{ partial "agent-v2-migration/list-main" . }} +
+
+{{ end }} \ No newline at end of file diff --git a/site/layouts/agent-v2-migration/single.html b/site/layouts/agent-v2-migration/single.html new file mode 100644 index 0000000000..e918630803 --- /dev/null +++ b/site/layouts/agent-v2-migration/single.html @@ -0,0 +1,49 @@ +{{ define "main" }} +
+ + + {{if (.Params.catalog) }} +
+ {{ else if and (gt .WordCount 200 ) (.Params.toc) }} +
+ {{ else }} +
+ {{ end }} + +
+
+ NGINX Agent v3 is available!

+ This documentation is for NGINX Agent v2. We suggest reading the Migrate from NGINX Agent v2 to v3 topic to learn the differences between the two versions, and learn how to upgrade your instances. +
+
+ +

{{ .Title }}

+ + {{ if eq .Page.Draft true }}{{ partial "draft-badge.html" . }}{{ end }} + {{ if .Description }}

{{ .Description | markdownify }}

{{ end}} + + {{ if in .Params.doctypes "beta" }}{{ partial "beta-badge" . }}{{ end }} + + {{ .Content }} + {{ partial "version-list" . }} +
+ {{ partial "previous-next-links-in-section-with-title.html" . }} + +
+ {{ if and (gt .WordCount 200 ) (.Params.toc) }} + {{ if (add (len (findRE " + {{ partial "toc.html" . }} +
+ {{ end }} + {{ end }} +
+ +{{if .Params.script}} + {{ $script := (delimit (slice "scripts" .Params.script) "/")}} + {{ partial (string $script) .}} +{{end }} + +{{ end }} \ No newline at end of file diff --git a/site/layouts/catalogs/single.html b/site/layouts/catalogs/single.html new file mode 100644 index 0000000000..57b1d77790 --- /dev/null +++ b/site/layouts/catalogs/single.html @@ -0,0 +1,14 @@ +{{ define "main" }} +
+ + + {{ .Content }} + +{{if .Params.script}} + {{ $script := (delimit (slice "scripts" .Params.script) "/")}} + {{ partial (string $script) .}} +{{end }} + +{{ end }} diff --git a/site/layouts/partials/agent-v2-migration/list-main.html b/site/layouts/partials/agent-v2-migration/list-main.html new file mode 100644 index 0000000000..51c39a214b --- /dev/null +++ b/site/layouts/partials/agent-v2-migration/list-main.html @@ -0,0 +1,53 @@ +
+
+ +
+ +
+
+
+ {{ range .Pages.GroupBy "Section" }} + + {{ range .Pages.ByWeight }} +
+
+

+ + {{ .Title }} +

+ {{/*}}

+ {{ if .Description }}{{ .Description | markdownify }}{{ end }} +

{{*/}} + +
+
+ + {{ end }} +
+
+ {{ end }} + + +
+ +
\ No newline at end of file diff --git a/site/layouts/shortcodes/v2-metrics.html b/site/layouts/shortcodes/v2-metrics.html new file mode 100644 index 0000000000..dc14d9a35e --- /dev/null +++ b/site/layouts/shortcodes/v2-metrics.html @@ -0,0 +1,56 @@ +
+ {{ range .Site.Data.v2metrics }} + +

{{.name}} + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
description{{.description}}
type{{.type}}
categories{{.categories}}
source{{.source}}
rollup_aggregate{{.rollup_aggregate}}
unit{{.unit}}
aggregations + {{ range .aggregations }} + {{ . }}; + {{end}} +
dimensions + {{ range sort .dimensions }} +
  • + {{ . }} +
  • + {{end}} +
    +
    + {{ end }} +
    \ No newline at end of file From 88fbfc2bbfdc796c673d1190c6f486197d9f186e Mon Sep 17 00:00:00 2001 From: oliveromahony Date: Mon, 2 Dec 2024 15:03:56 +0000 Subject: [PATCH 3/7] Fix race condition test (#936) * fix the flaky unit tests - the integration tests may still be problematic --- go.mod | 22 +++--- go.sum | 74 ++++++++----------- internal/collector/otel_collector_plugin.go | 8 +- .../collector/otel_collector_plugin_test.go | 6 ++ .../grpc/mock_management_command_service.go | 1 + 5 files changed, 55 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index 5e04344553..78b1b20f06 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/docker/docker v27.3.1+incompatible github.com/fsnotify/fsnotify v1.8.0 - github.com/go-resty/resty/v2 v2.13.1 + github.com/go-resty/resty/v2 v2.16.2 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 @@ -90,10 +90,12 @@ require ( github.com/apache/thrift v0.21.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect + github.com/bytedance/sonic v1.12.5 // indirect + github.com/bytedance/sonic/loader v0.2.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/cpuguy83/dockercfg v0.3.2 // indirect @@ -107,7 +109,7 @@ require ( github.com/expr-lang/expr v1.16.9 // indirect github.com/fatih/color v1.17.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -116,7 +118,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.19.0 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.3 // indirect @@ -141,7 +143,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/jstemmer/go-junit-report v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/knadh/koanf/maps v0.1.1 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.2 // indirect @@ -278,12 +280,12 @@ require ( go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.7.0 // indirect + golang.org/x/arch v0.12.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.25.0 // indirect gonum.org/v1/gonum v0.15.1 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -294,7 +296,7 @@ require ( ) require ( - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.10.0 github.com/mattn/go-isatty v0.0.20 // indirect github.com/nginxinc/nginx-go-crossplane v0.4.46 github.com/prometheus/client_golang v1.20.5 // indirect @@ -309,5 +311,5 @@ require ( golang.org/x/net v0.31.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect - google.golang.org/grpc v1.67.1 + google.golang.org/grpc v1.68.0 ) diff --git a/go.sum b/go.sum index 5f48985c72..2f7075d330 100644 --- a/go.sum +++ b/go.sum @@ -60,9 +60,11 @@ github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0 github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bufbuild/protovalidate-go v0.2.1 h1:pJr07sYhliyfj/STAM7hU4J3FKpVeLVKvOBmOTN8j+s= github.com/bufbuild/protovalidate-go v0.2.1/go.mod h1:e7XXDtlxj5vlEyAgsrxpzayp4cEMKCSSb8ZCkin+MVA= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w= +github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E= +github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -70,13 +72,14 @@ github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMr github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg= -github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= +github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= @@ -131,12 +134,12 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/ github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= @@ -163,10 +166,10 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= -github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g= -github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= +github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= @@ -307,14 +310,15 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= github.com/knadh/koanf/v2 v2.1.2 h1:I2rtLRqXRy1p01m/utEtpZSSA6dcJbgGVuE27kW2PzQ= github.com/knadh/koanf/v2 v2.1.2/go.mod h1:Gphfaen0q1Fc1HTgJgSTC4oRX9R2R5ErYMZJy8fLJBo= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -794,15 +798,12 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg= +golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -815,7 +816,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -830,11 +830,7 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -846,7 +842,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -867,29 +862,19 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -902,7 +887,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -921,16 +905,16 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -979,7 +963,7 @@ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7F k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/internal/collector/otel_collector_plugin.go b/internal/collector/otel_collector_plugin.go index 4e3f1a85f0..76a821b322 100644 --- a/internal/collector/otel_collector_plugin.go +++ b/internal/collector/otel_collector_plugin.go @@ -39,10 +39,16 @@ type ( } ) -var _ bus.Plugin = (*Collector)(nil) +var ( + _ bus.Plugin = (*Collector)(nil) + initMutex = &sync.Mutex{} +) // NewCollector is the constructor for the Collector plugin. func New(conf *config.Config) (*Collector, error) { + initMutex.Lock() + + defer initMutex.Unlock() if conf == nil { return nil, errors.New("nil agent config") } diff --git a/internal/collector/otel_collector_plugin_test.go b/internal/collector/otel_collector_plugin_test.go index 941b4c24c3..002df2c8ec 100644 --- a/internal/collector/otel_collector_plugin_test.go +++ b/internal/collector/otel_collector_plugin_test.go @@ -511,6 +511,8 @@ func TestCollector_updateExistingNginxOSSReceiver(t *testing.T) { collector, err := New(conf) require.NoError(tt, err, "NewCollector should not return an error with valid config") + collector.service = createFakeCollector() + nginxReceiverFound, reloadCollector := collector.updateExistingNginxOSSReceiver(test.nginxConfigContext) assert.True(tt, nginxReceiverFound) @@ -580,6 +582,8 @@ func TestCollector_updateExistingNginxPlusReceiver(t *testing.T) { collector, err := New(conf) require.NoError(tt, err, "NewCollector should not return an error with valid config") + collector.service = createFakeCollector() + nginxReceiverFound, reloadCollector := collector.updateExistingNginxPlusReceiver(test.nginxConfigContext) assert.True(tt, nginxReceiverFound) @@ -633,6 +637,8 @@ func TestCollector_updateResourceAttributes(t *testing.T) { collector, err := New(conf) require.NoError(tt, err, "NewCollector should not return an error with valid config") + collector.service = createFakeCollector() + // set up Actions conf.Collector.Processors.Resource = &config.Resource{Attributes: test.setup} diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 9fa4cdf2cf..9d1192ea40 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -236,6 +236,7 @@ func (cs *CommandService) listenForDataPlaneResponses(ctx context.Context, in mp func (cs *CommandService) createServer(logger *slog.Logger) { cs.server = gin.New() + cs.server.Use(gin.Recovery()) cs.server.UseRawPath = true cs.server.Use(sloggin.NewWithConfig(logger, sloggin.Config{DefaultLevel: slog.LevelDebug})) From 6f9ec55aecd0eb59e174bf3153f04803fa911c19 Mon Sep 17 00:00:00 2001 From: oliveromahony Date: Thu, 5 Dec 2024 11:45:51 +0000 Subject: [PATCH 4/7] Add TLS configuration for the command server to the proto definitions (#861) * add TLS configuration for the command server to the proto definitions --------- Co-authored-by: dhurley --- api/grpc/mpi/v1/command.pb.go | 126 ++++--- api/grpc/mpi/v1/command.pb.validate.go | 87 +++++ api/grpc/mpi/v1/command.proto | 11 +- api/grpc/mpi/v1/common.pb.go | 297 ++++++++++++++++- api/grpc/mpi/v1/common.pb.validate.go | 314 ++++++++++++++++++ api/grpc/mpi/v1/common.proto | 36 ++ docs/proto/protos.md | 72 +++- internal/config/mapper.go | 82 +++++ internal/config/mapper_test.go | 221 ++++++++++++ .../instance/instance_watcher_service.go | 2 +- 10 files changed, 1187 insertions(+), 61 deletions(-) create mode 100644 internal/config/mapper.go create mode 100644 internal/config/mapper_test.go diff --git a/api/grpc/mpi/v1/command.pb.go b/api/grpc/mpi/v1/command.pb.go index e390eb5ac1..af409f1023 100644 --- a/api/grpc/mpi/v1/command.pb.go +++ b/api/grpc/mpi/v1/command.pb.go @@ -1949,11 +1949,18 @@ func (x *AgentConfig) GetMessageBufferSize() string { return "" } -// The command settings, associated with messaging from an external source +// The command server settings, associated with messaging from an external source type CommandServer struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Server configuration (e.g., host, port, type) + Server *ServerSettings `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` + // Authentication configuration (e.g., token) + Auth *AuthSettings `protobuf:"bytes,2,opt,name=auth,proto3" json:"auth,omitempty"` + // TLS configuration for secure communication + Tls *TLSSettings `protobuf:"bytes,3,opt,name=tls,proto3" json:"tls,omitempty"` } func (x *CommandServer) Reset() { @@ -1986,6 +1993,27 @@ func (*CommandServer) Descriptor() ([]byte, []int) { return file_mpi_v1_command_proto_rawDescGZIP(), []int{28} } +func (x *CommandServer) GetServer() *ServerSettings { + if x != nil { + return x.Server + } + return nil +} + +func (x *CommandServer) GetAuth() *AuthSettings { + if x != nil { + return x.Auth + } + return nil +} + +func (x *CommandServer) GetTls() *TLSSettings { + if x != nil { + return x.Tls + } + return nil +} + // The metrics settings associated with origins (sources) of the metrics and destinations (exporter) type MetricsServer struct { state protoimpl.MessageState @@ -2360,35 +2388,43 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 0x2e, 0x0a, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, - 0x0f, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x22, 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x32, - 0x87, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, - 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, - 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x24, 0x2e, 0x6d, + 0x90, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x28, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x03, 0x74, + 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x74, + 0x6c, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x32, 0x87, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, + 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, - 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x6d, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x24, + 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, + 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x6d, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2443,6 +2479,9 @@ var file_mpi_v1_command_proto_goTypes = []any{ (*CommandResponse)(nil), // 34: mpi.v1.CommandResponse (*FileOverview)(nil), // 35: mpi.v1.FileOverview (*structpb.Struct)(nil), // 36: google.protobuf.Struct + (*ServerSettings)(nil), // 37: mpi.v1.ServerSettings + (*AuthSettings)(nil), // 38: mpi.v1.AuthSettings + (*TLSSettings)(nil), // 39: mpi.v1.TLSSettings } var file_mpi_v1_command_proto_depIdxs = []int32{ 33, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta @@ -2482,19 +2521,22 @@ var file_mpi_v1_command_proto_depIdxs = []int32{ 31, // 34: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer 32, // 35: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer 36, // 36: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct - 2, // 37: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest - 8, // 38: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest - 11, // 39: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest - 13, // 40: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse - 7, // 41: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse - 9, // 42: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse - 12, // 43: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse - 14, // 44: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest - 41, // [41:45] is the sub-list for method output_type - 37, // [37:41] is the sub-list for method input_type - 37, // [37:37] is the sub-list for extension type_name - 37, // [37:37] is the sub-list for extension extendee - 0, // [0:37] is the sub-list for field type_name + 37, // 37: mpi.v1.CommandServer.server:type_name -> mpi.v1.ServerSettings + 38, // 38: mpi.v1.CommandServer.auth:type_name -> mpi.v1.AuthSettings + 39, // 39: mpi.v1.CommandServer.tls:type_name -> mpi.v1.TLSSettings + 2, // 40: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest + 8, // 41: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest + 11, // 42: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest + 13, // 43: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse + 7, // 44: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse + 9, // 45: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse + 12, // 46: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse + 14, // 47: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest + 44, // [44:48] is the sub-list for method output_type + 40, // [40:44] is the sub-list for method input_type + 40, // [40:40] is the sub-list for extension type_name + 40, // [40:40] is the sub-list for extension extendee + 0, // [0:40] is the sub-list for field type_name } func init() { file_mpi_v1_command_proto_init() } diff --git a/api/grpc/mpi/v1/command.pb.validate.go b/api/grpc/mpi/v1/command.pb.validate.go index cc3233ba29..e23a11dae6 100644 --- a/api/grpc/mpi/v1/command.pb.validate.go +++ b/api/grpc/mpi/v1/command.pb.validate.go @@ -4121,6 +4121,93 @@ func (m *CommandServer) validate(all bool) error { var errors []error + if all { + switch v := interface{}(m.GetServer()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetServer()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CommandServerValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetAuth()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Auth", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Auth", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetAuth()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CommandServerValidationError{ + field: "Auth", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetTls()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Tls", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CommandServerValidationError{ + field: "Tls", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetTls()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CommandServerValidationError{ + field: "Tls", + reason: "embedded message failed validation", + cause: err, + } + } + } + if len(errors) > 0 { return CommandServerMultiError(errors) } diff --git a/api/grpc/mpi/v1/command.proto b/api/grpc/mpi/v1/command.proto index f7879ea28c..8a5cd5f617 100644 --- a/api/grpc/mpi/v1/command.proto +++ b/api/grpc/mpi/v1/command.proto @@ -323,8 +323,15 @@ message AgentConfig { string message_buffer_size = 6; } -// The command settings, associated with messaging from an external source -message CommandServer {} +// The command server settings, associated with messaging from an external source +message CommandServer { + // Server configuration (e.g., host, port, type) + mpi.v1.ServerSettings server = 1; + // Authentication configuration (e.g., token) + mpi.v1.AuthSettings auth = 2; + // TLS configuration for secure communication + mpi.v1.TLSSettings tls = 3; +} // The metrics settings associated with origins (sources) of the metrics and destinations (exporter) message MetricsServer {} diff --git a/api/grpc/mpi/v1/common.pb.go b/api/grpc/mpi/v1/common.pb.go index 8f28d16ed7..008b7b98ff 100644 --- a/api/grpc/mpi/v1/common.pb.go +++ b/api/grpc/mpi/v1/common.pb.go @@ -88,6 +88,58 @@ func (CommandResponse_CommandStatus) EnumDescriptor() ([]byte, []int) { return file_mpi_v1_common_proto_rawDescGZIP(), []int{1, 0} } +type ServerSettings_ServerType int32 + +const ( + // Undefined server type + ServerSettings_SERVER_SETTINGS_TYPE_UNDEFINED ServerSettings_ServerType = 0 + // gRPC server type + ServerSettings_SERVER_SETTINGS_TYPE_GRPC ServerSettings_ServerType = 1 + // HTTP server type + ServerSettings_SERVER_SETTINGS_TYPE_HTTP ServerSettings_ServerType = 2 +) + +// Enum value maps for ServerSettings_ServerType. +var ( + ServerSettings_ServerType_name = map[int32]string{ + 0: "SERVER_SETTINGS_TYPE_UNDEFINED", + 1: "SERVER_SETTINGS_TYPE_GRPC", + 2: "SERVER_SETTINGS_TYPE_HTTP", + } + ServerSettings_ServerType_value = map[string]int32{ + "SERVER_SETTINGS_TYPE_UNDEFINED": 0, + "SERVER_SETTINGS_TYPE_GRPC": 1, + "SERVER_SETTINGS_TYPE_HTTP": 2, + } +) + +func (x ServerSettings_ServerType) Enum() *ServerSettings_ServerType { + p := new(ServerSettings_ServerType) + *p = x + return p +} + +func (x ServerSettings_ServerType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServerSettings_ServerType) Descriptor() protoreflect.EnumDescriptor { + return file_mpi_v1_common_proto_enumTypes[1].Descriptor() +} + +func (ServerSettings_ServerType) Type() protoreflect.EnumType { + return &file_mpi_v1_common_proto_enumTypes[1] +} + +func (x ServerSettings_ServerType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServerSettings_ServerType.Descriptor instead. +func (ServerSettings_ServerType) EnumDescriptor() ([]byte, []int) { + return file_mpi_v1_common_proto_rawDescGZIP(), []int{2, 0} +} + // Meta-information associated with a message type MessageMeta struct { state protoimpl.MessageState @@ -218,6 +270,191 @@ func (x *CommandResponse) GetError() string { return "" } +// The top-level configuration for the command server +type ServerSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Command server host + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // Command server port + Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` + // Server type (enum for gRPC, HTTP, etc.) + Type ServerSettings_ServerType `protobuf:"varint,3,opt,name=type,proto3,enum=mpi.v1.ServerSettings_ServerType" json:"type,omitempty"` +} + +func (x *ServerSettings) Reset() { + *x = ServerSettings{} + mi := &file_mpi_v1_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ServerSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServerSettings) ProtoMessage() {} + +func (x *ServerSettings) ProtoReflect() protoreflect.Message { + mi := &file_mpi_v1_common_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServerSettings.ProtoReflect.Descriptor instead. +func (*ServerSettings) Descriptor() ([]byte, []int) { + return file_mpi_v1_common_proto_rawDescGZIP(), []int{2} +} + +func (x *ServerSettings) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *ServerSettings) GetPort() int32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *ServerSettings) GetType() ServerSettings_ServerType { + if x != nil { + return x.Type + } + return ServerSettings_SERVER_SETTINGS_TYPE_UNDEFINED +} + +// Defines the authentication configuration +type AuthSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AuthSettings) Reset() { + *x = AuthSettings{} + mi := &file_mpi_v1_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthSettings) ProtoMessage() {} + +func (x *AuthSettings) ProtoReflect() protoreflect.Message { + mi := &file_mpi_v1_common_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthSettings.ProtoReflect.Descriptor instead. +func (*AuthSettings) Descriptor() ([]byte, []int) { + return file_mpi_v1_common_proto_rawDescGZIP(), []int{3} +} + +type TLSSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // TLS certificate for the command server (e.g., "/path/to/cert.pem") + Cert string `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` + // TLS key for the command server (e.g., "/path/to/key.pem") + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // CA certificate for the command server (e.g., "/path/to/ca.pem") + Ca string `protobuf:"bytes,3,opt,name=ca,proto3" json:"ca,omitempty"` + // Controls whether a client verifies the server's certificate chain and host name. + // If skip_verify is true, accepts any certificate presented by the server and any host name in that certificate. + SkipVerify bool `protobuf:"varint,4,opt,name=skip_verify,json=skipVerify,proto3" json:"skip_verify,omitempty"` + // Server name for TLS + ServerName string `protobuf:"bytes,5,opt,name=server_name,json=serverName,proto3" json:"server_name,omitempty"` +} + +func (x *TLSSettings) Reset() { + *x = TLSSettings{} + mi := &file_mpi_v1_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TLSSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TLSSettings) ProtoMessage() {} + +func (x *TLSSettings) ProtoReflect() protoreflect.Message { + mi := &file_mpi_v1_common_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TLSSettings.ProtoReflect.Descriptor instead. +func (*TLSSettings) Descriptor() ([]byte, []int) { + return file_mpi_v1_common_proto_rawDescGZIP(), []int{4} +} + +func (x *TLSSettings) GetCert() string { + if x != nil { + return x.Cert + } + return "" +} + +func (x *TLSSettings) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *TLSSettings) GetCa() string { + if x != nil { + return x.Ca + } + return "" +} + +func (x *TLSSettings) GetSkipVerify() bool { + if x != nil { + return x.SkipVerify + } + return false +} + +func (x *TLSSettings) GetServerName() string { + if x != nil { + return x.ServerName + } + return "" +} + var File_mpi_v1_common_proto protoreflect.FileDescriptor var file_mpi_v1_common_proto_rawDesc = []byte{ @@ -253,8 +490,33 @@ var file_mpi_v1_common_proto_rawDesc = []byte{ 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x04, 0x42, 0x08, 0x5a, - 0x06, 0x6d, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x04, 0x22, 0xec, 0x01, + 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x1a, 0x06, 0x18, 0xff, 0xff, 0x03, 0x28, 0x01, 0x52, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x6e, 0x0a, 0x0a, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x45, + 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, + 0x0a, 0x19, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, + 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x01, 0x12, 0x1d, 0x0a, + 0x19, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x53, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x02, 0x22, 0x0e, 0x0a, 0x0c, + 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x85, 0x01, 0x0a, + 0x0b, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x63, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x5a, 0x06, 0x6d, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -269,22 +531,27 @@ func file_mpi_v1_common_proto_rawDescGZIP() []byte { return file_mpi_v1_common_proto_rawDescData } -var file_mpi_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_mpi_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_mpi_v1_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_mpi_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_mpi_v1_common_proto_goTypes = []any{ (CommandResponse_CommandStatus)(0), // 0: mpi.v1.CommandResponse.CommandStatus - (*MessageMeta)(nil), // 1: mpi.v1.MessageMeta - (*CommandResponse)(nil), // 2: mpi.v1.CommandResponse - (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (ServerSettings_ServerType)(0), // 1: mpi.v1.ServerSettings.ServerType + (*MessageMeta)(nil), // 2: mpi.v1.MessageMeta + (*CommandResponse)(nil), // 3: mpi.v1.CommandResponse + (*ServerSettings)(nil), // 4: mpi.v1.ServerSettings + (*AuthSettings)(nil), // 5: mpi.v1.AuthSettings + (*TLSSettings)(nil), // 6: mpi.v1.TLSSettings + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp } var file_mpi_v1_common_proto_depIdxs = []int32{ - 3, // 0: mpi.v1.MessageMeta.timestamp:type_name -> google.protobuf.Timestamp + 7, // 0: mpi.v1.MessageMeta.timestamp:type_name -> google.protobuf.Timestamp 0, // 1: mpi.v1.CommandResponse.status:type_name -> mpi.v1.CommandResponse.CommandStatus - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 2: mpi.v1.ServerSettings.type:type_name -> mpi.v1.ServerSettings.ServerType + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_mpi_v1_common_proto_init() } @@ -297,8 +564,8 @@ func file_mpi_v1_common_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mpi_v1_common_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, + NumEnums: 2, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/api/grpc/mpi/v1/common.pb.validate.go b/api/grpc/mpi/v1/common.pb.validate.go index f057af507f..e462feaee8 100644 --- a/api/grpc/mpi/v1/common.pb.validate.go +++ b/api/grpc/mpi/v1/common.pb.validate.go @@ -272,3 +272,317 @@ var _ interface { Cause() error ErrorName() string } = CommandResponseValidationError{} + +// Validate checks the field values on ServerSettings with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ServerSettings) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ServerSettings with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ServerSettingsMultiError, +// or nil if none found. +func (m *ServerSettings) ValidateAll() error { + return m.validate(true) +} + +func (m *ServerSettings) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Host + + // no validation rules for Port + + // no validation rules for Type + + if len(errors) > 0 { + return ServerSettingsMultiError(errors) + } + + return nil +} + +// ServerSettingsMultiError is an error wrapping multiple validation errors +// returned by ServerSettings.ValidateAll() if the designated constraints +// aren't met. +type ServerSettingsMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ServerSettingsMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ServerSettingsMultiError) AllErrors() []error { return m } + +// ServerSettingsValidationError is the validation error returned by +// ServerSettings.Validate if the designated constraints aren't met. +type ServerSettingsValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ServerSettingsValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ServerSettingsValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ServerSettingsValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ServerSettingsValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ServerSettingsValidationError) ErrorName() string { return "ServerSettingsValidationError" } + +// Error satisfies the builtin error interface +func (e ServerSettingsValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sServerSettings.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ServerSettingsValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ServerSettingsValidationError{} + +// Validate checks the field values on AuthSettings with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *AuthSettings) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on AuthSettings with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in AuthSettingsMultiError, or +// nil if none found. +func (m *AuthSettings) ValidateAll() error { + return m.validate(true) +} + +func (m *AuthSettings) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return AuthSettingsMultiError(errors) + } + + return nil +} + +// AuthSettingsMultiError is an error wrapping multiple validation errors +// returned by AuthSettings.ValidateAll() if the designated constraints aren't met. +type AuthSettingsMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m AuthSettingsMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m AuthSettingsMultiError) AllErrors() []error { return m } + +// AuthSettingsValidationError is the validation error returned by +// AuthSettings.Validate if the designated constraints aren't met. +type AuthSettingsValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e AuthSettingsValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e AuthSettingsValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e AuthSettingsValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e AuthSettingsValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e AuthSettingsValidationError) ErrorName() string { return "AuthSettingsValidationError" } + +// Error satisfies the builtin error interface +func (e AuthSettingsValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sAuthSettings.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = AuthSettingsValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = AuthSettingsValidationError{} + +// Validate checks the field values on TLSSettings with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *TLSSettings) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on TLSSettings with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in TLSSettingsMultiError, or +// nil if none found. +func (m *TLSSettings) ValidateAll() error { + return m.validate(true) +} + +func (m *TLSSettings) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Cert + + // no validation rules for Key + + // no validation rules for Ca + + // no validation rules for SkipVerify + + // no validation rules for ServerName + + if len(errors) > 0 { + return TLSSettingsMultiError(errors) + } + + return nil +} + +// TLSSettingsMultiError is an error wrapping multiple validation errors +// returned by TLSSettings.ValidateAll() if the designated constraints aren't met. +type TLSSettingsMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m TLSSettingsMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m TLSSettingsMultiError) AllErrors() []error { return m } + +// TLSSettingsValidationError is the validation error returned by +// TLSSettings.Validate if the designated constraints aren't met. +type TLSSettingsValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e TLSSettingsValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e TLSSettingsValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e TLSSettingsValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e TLSSettingsValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e TLSSettingsValidationError) ErrorName() string { return "TLSSettingsValidationError" } + +// Error satisfies the builtin error interface +func (e TLSSettingsValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sTLSSettings.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = TLSSettingsValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = TLSSettingsValidationError{} diff --git a/api/grpc/mpi/v1/common.proto b/api/grpc/mpi/v1/common.proto index e02e74f3c6..d35406b16b 100644 --- a/api/grpc/mpi/v1/common.proto +++ b/api/grpc/mpi/v1/common.proto @@ -43,3 +43,39 @@ message CommandResponse { // Provides an error message of why the command failed, only populated when CommandStatus is COMMAND_STATUS_ERROR string error = 3; } + +// The top-level configuration for the command server +message ServerSettings { + // Command server host + string host = 1; + // Command server port + int32 port = 2 [(buf.validate.field).int32 = {gte: 1, lte: 65535}]; + // Server type (enum for gRPC, HTTP, etc.) + ServerType type = 3; + enum ServerType { + // Undefined server type + SERVER_SETTINGS_TYPE_UNDEFINED = 0; + // gRPC server type + SERVER_SETTINGS_TYPE_GRPC = 1; + // HTTP server type + SERVER_SETTINGS_TYPE_HTTP = 2; + } +} + +// Defines the authentication configuration +message AuthSettings { +} + +message TLSSettings { + // TLS certificate for the command server (e.g., "/path/to/cert.pem") + string cert = 1; + // TLS key for the command server (e.g., "/path/to/key.pem") + string key = 2; + // CA certificate for the command server (e.g., "/path/to/ca.pem") + string ca = 3; + // Controls whether a client verifies the server's certificate chain and host name. + // If skip_verify is true, accepts any certificate presented by the server and any host name in that certificate. + bool skip_verify = 4; + // Server name for TLS + string server_name = 5; +} diff --git a/docs/proto/protos.md b/docs/proto/protos.md index 9e7a8afd6e..d926a358d9 100644 --- a/docs/proto/protos.md +++ b/docs/proto/protos.md @@ -4,10 +4,14 @@ ## Table of Contents - [mpi/v1/common.proto](#mpi_v1_common-proto) + - [AuthSettings](#mpi-v1-AuthSettings) - [CommandResponse](#mpi-v1-CommandResponse) - [MessageMeta](#mpi-v1-MessageMeta) + - [ServerSettings](#mpi-v1-ServerSettings) + - [TLSSettings](#mpi-v1-TLSSettings) - [CommandResponse.CommandStatus](#mpi-v1-CommandResponse-CommandStatus) + - [ServerSettings.ServerType](#mpi-v1-ServerSettings-ServerType) - [mpi/v1/files.proto](#mpi_v1_files-proto) - [AttributeTypeAndValue](#mpi-v1-AttributeTypeAndValue) @@ -86,6 +90,16 @@ This source code is licensed under the Apache License, Version 2.0 license found LICENSE file in the root directory of this source tree. + + +### AuthSettings +Defines the authentication configuration + + + + + + ### CommandResponse @@ -119,6 +133,42 @@ Meta-information associated with a message + + + +### ServerSettings +The top-level configuration for the command server + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| host | [string](#string) | | Command server host | +| port | [int32](#int32) | | Command server port | +| type | [ServerSettings.ServerType](#mpi-v1-ServerSettings-ServerType) | | Server type (enum for gRPC, HTTP, etc.) | + + + + + + + + +### TLSSettings + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| cert | [string](#string) | | TLS certificate for the command server (e.g., "/path/to/cert.pem") | +| key | [string](#string) | | TLS key for the command server (e.g., "/path/to/key.pem") | +| ca | [string](#string) | | CA certificate for the command server (e.g., "/path/to/ca.pem") | +| skip_verify | [bool](#bool) | | Controls whether a client verifies the server's certificate chain and host name. If skip_verify is true, accepts any certificate presented by the server and any host name in that certificate. | +| server_name | [string](#string) | | Server name for TLS | + + + + + @@ -136,6 +186,19 @@ Command status enum | COMMAND_STATUS_FAILURE | 4 | Command failure | + + + +### ServerSettings.ServerType + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| SERVER_SETTINGS_TYPE_UNDEFINED | 0 | Undefined server type | +| SERVER_SETTINGS_TYPE_GRPC | 1 | gRPC server type | +| SERVER_SETTINGS_TYPE_HTTP | 2 | HTTP server type | + + @@ -559,7 +622,14 @@ This contains a series of NGINX Agent configurations ### CommandServer -The command settings, associated with messaging from an external source +The command server settings, associated with messaging from an external source + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| server | [ServerSettings](#mpi-v1-ServerSettings) | | Server configuration (e.g., host, port, type) | +| auth | [AuthSettings](#mpi-v1-AuthSettings) | | Authentication configuration (e.g., token) | +| tls | [TLSSettings](#mpi-v1-TLSSettings) | | TLS configuration for secure communication | diff --git a/internal/config/mapper.go b/internal/config/mapper.go new file mode 100644 index 0000000000..c9e85e6428 --- /dev/null +++ b/internal/config/mapper.go @@ -0,0 +1,82 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package config + +import ( + "log/slog" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" +) + +// FromCommandProto maps the AgentConfig Command struct to the Command proto message +func FromCommandProto(config *mpi.CommandServer) *Command { + cmd := &Command{} + + // Map ServerSettings to the ServerConfig + if config.GetServer() != nil && config.GetServer().GetHost() != "" && config.GetServer().GetPort() != 0 { + cmd.Server = &ServerConfig{ + Host: config.GetServer().GetHost(), + Port: int(config.GetServer().GetPort()), + } + if config.GetServer().GetType() != mpi.ServerSettings_SERVER_SETTINGS_TYPE_UNDEFINED { + cmd.Server.Type = ServerType(config.GetServer().GetType()) + } + } else { + cmd.Server = nil + } + // Set Auth to be nil + cmd.Auth = nil + + // Map TLSSettings to TLSConfig + if config.GetTls() != nil { + cmd.TLS = &TLSConfig{ + Cert: config.GetTls().GetCert(), + Key: config.GetTls().GetKey(), + Ca: config.GetTls().GetCa(), + ServerName: config.GetTls().GetServerName(), + SkipVerify: config.GetTls().GetSkipVerify(), + } + if cmd.TLS.SkipVerify { + slog.Warn("Insecure setting SkipVerify, this tells the server to accept a certificate with any hostname.") + } + } else { + cmd.TLS = nil + } + + return cmd +} + +// ToCommandProto maps the AgentConfig Command struct back to the Command proto message +func ToCommandProto(cmd *Command) *mpi.CommandServer { + protoConfig := &mpi.CommandServer{} + + // Map ServerConfig to the ServerSettings + if cmd.Server != nil { + protoConfig.Server = &mpi.ServerSettings{ + Host: cmd.Server.Host, + Port: int32(cmd.Server.Port), + Type: mpi.ServerSettings_ServerType(cmd.Server.Type + 1), + } + } + + // Map AuthConfig to AuthSettings + if cmd.Auth != nil { + protoConfig.Auth = &mpi.AuthSettings{} + } + + // Map TLSConfig to TLSSettings + if cmd.TLS != nil { + protoConfig.Tls = &mpi.TLSSettings{ + Cert: cmd.TLS.Cert, + Key: cmd.TLS.Key, + Ca: cmd.TLS.Ca, + ServerName: cmd.TLS.ServerName, + SkipVerify: cmd.TLS.SkipVerify, + } + } + + return protoConfig +} diff --git a/internal/config/mapper_test.go b/internal/config/mapper_test.go new file mode 100644 index 0000000000..7b6e857986 --- /dev/null +++ b/internal/config/mapper_test.go @@ -0,0 +1,221 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. +package config + +import ( + "testing" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/stretchr/testify/assert" +) + +func TestFromCommandProto(t *testing.T) { + tests := []struct { + protoConfig *mpi.CommandServer + expected *Command + name string + }{ + { + name: "Test 1: Valid input with all fields", + protoConfig: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 1, + }, + Auth: &mpi.AuthSettings{}, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + expected: &Command{ + Server: getAgentConfig().Command.Server, + Auth: nil, + TLS: getAgentConfig().Command.TLS, + }, + }, + { + name: "Test 2: Missing server", + protoConfig: &mpi.CommandServer{ + Auth: &mpi.AuthSettings{}, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + expected: &Command{ + Server: nil, + Auth: nil, + TLS: getAgentConfig().Command.TLS, + }, + }, + { + name: "Test 3: Missing auth", + protoConfig: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 1, // gRPC + }, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + expected: &Command{ + Server: getAgentConfig().Command.Server, + Auth: nil, + TLS: getAgentConfig().Command.TLS, + }, + }, + { + name: "Test 4: Missing TLS", + protoConfig: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 1, // Change to HTTP when supported + }, + Auth: &mpi.AuthSettings{}, + }, + expected: &Command{ + Server: getAgentConfig().Command.Server, + Auth: nil, + TLS: nil, + }, + }, + { + name: "Test 5: Empty input", + protoConfig: &mpi.CommandServer{}, + expected: &Command{ + Server: nil, + Auth: nil, + TLS: nil, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := FromCommandProto(tt.protoConfig) + assert.Equal(t, tt.expected, config) + }) + } +} + +func TestToCommandProto(t *testing.T) { + tests := []struct { + cmd *Command + expected *mpi.CommandServer + name string + }{ + { + name: "Test 1: Valid input with all fields", + cmd: &Command{ + Server: getAgentConfig().Command.Server, + Auth: getAgentConfig().Command.Auth, + TLS: getAgentConfig().Command.TLS, + }, + expected: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 2, + }, + Auth: &mpi.AuthSettings{}, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + }, + { + name: "Test 2: Missing server", + cmd: &Command{ + Server: nil, + Auth: getAgentConfig().Command.Auth, + TLS: getAgentConfig().Command.TLS, + }, + expected: &mpi.CommandServer{ + Server: nil, + Auth: &mpi.AuthSettings{}, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + }, + { + name: "Test 3: Missing auth", + cmd: &Command{ + Server: getAgentConfig().Command.Server, + Auth: nil, + TLS: getAgentConfig().Command.TLS, + }, + expected: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 2, // gRPC + }, + Tls: &mpi.TLSSettings{ + Cert: getAgentConfig().Command.TLS.Cert, + Key: getAgentConfig().Command.TLS.Key, + Ca: getAgentConfig().Command.TLS.Ca, + ServerName: getAgentConfig().Command.TLS.ServerName, + SkipVerify: getAgentConfig().Command.TLS.SkipVerify, + }, + }, + }, + { + name: "Test 4: Missing TLS", + cmd: &Command{ + Server: getAgentConfig().Command.Server, + Auth: getAgentConfig().Command.Auth, + TLS: nil, + }, + expected: &mpi.CommandServer{ + Server: &mpi.ServerSettings{ + Host: getAgentConfig().Command.Server.Host, + Port: int32(getAgentConfig().Command.Server.Port), + Type: 2, + }, + Auth: &mpi.AuthSettings{}, + }, + }, + { + name: "Test 5: Empty input", + cmd: &Command{}, + expected: &mpi.CommandServer{ + Server: nil, + Auth: nil, + Tls: nil, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + protoConfig := ToCommandProto(tt.cmd) + assert.Equal(t, tt.expected, protoConfig) + }) + } +} diff --git a/internal/watcher/instance/instance_watcher_service.go b/internal/watcher/instance/instance_watcher_service.go index 958ad96866..a7aaec4c1c 100644 --- a/internal/watcher/instance/instance_watcher_service.go +++ b/internal/watcher/instance/instance_watcher_service.go @@ -295,7 +295,7 @@ func (iw *InstanceWatcherService) agentInstance(ctx context.Context) *mpi.Instan Actions: []*mpi.InstanceAction{}, Config: &mpi.InstanceConfig_AgentConfig{ AgentConfig: &mpi.AgentConfig{ - Command: &mpi.CommandServer{}, + Command: config.ToCommandProto(iw.agentConfig.Command), Metrics: &mpi.MetricsServer{}, File: &mpi.FileServer{}, Labels: []*structpb.Struct{}, From 0c83c0c4dcaa56e4c90520941ef886fbe65b71e1 Mon Sep 17 00:00:00 2001 From: aphralG <108004222+aphralG@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:36:27 +0000 Subject: [PATCH 5/7] Support unix socket to collect NGINX OSS and Plus metrics (#938) --- api/grpc/mpi/v1/command.pb.go | 374 ++++++++++-------- api/grpc/mpi/v1/command.pb.validate.go | 190 ++++++++- api/grpc/mpi/v1/command.proto | 31 +- docs/proto/protos.md | 23 +- go.mod | 4 +- go.sum | 4 +- internal/collector/nginxossreceiver/README.md | 11 +- .../internal/config/config.go | 15 +- .../scraper/stubstatus/stub_status_scraper.go | 16 +- .../stubstatus/stub_status_scraper_test.go | 31 +- .../collector/nginxplusreceiver/README.md | 12 +- .../collector/nginxplusreceiver/config.go | 30 +- .../collector/nginxplusreceiver/factory.go | 16 - .../collector/nginxplusreceiver/scraper.go | 23 +- .../nginxplusreceiver/scraper_test.go | 2 +- internal/collector/otel_collector_plugin.go | 34 +- .../collector/otel_collector_plugin_test.go | 114 +++++- internal/collector/otelcol.tmpl | 10 +- internal/collector/settings_test.go | 6 +- internal/config/config_test.go | 5 +- internal/config/types.go | 12 +- internal/model/config.go | 20 +- internal/model/config_test.go | 20 +- .../instance/instance_watcher_service.go | 46 ++- .../instance/instance_watcher_service_test.go | 32 +- .../watcher/instance/nginx_config_parser.go | 205 +++++----- .../instance/nginx_config_parser_test.go | 322 +++++++++++---- .../watcher/instance/nginx_process_parser.go | 15 +- internal/watcher/watcher_plugin.go | 3 +- .../test-opentelemetry-collector-agent.yaml | 5 +- test/model/config.go | 10 + test/protos/instances.go | 107 ++--- 32 files changed, 1231 insertions(+), 517 deletions(-) diff --git a/api/grpc/mpi/v1/command.pb.go b/api/grpc/mpi/v1/command.pb.go index af409f1023..ada6092b90 100644 --- a/api/grpc/mpi/v1/command.pb.go +++ b/api/grpc/mpi/v1/command.pb.go @@ -1651,8 +1651,8 @@ type NGINXRuntimeInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // the stub status API URL - StubStatus string `protobuf:"bytes,1,opt,name=stub_status,json=stubStatus,proto3" json:"stub_status,omitempty"` + // the stub status API details + StubStatus *APIDetails `protobuf:"bytes,1,opt,name=stub_status,json=stubStatus,proto3" json:"stub_status,omitempty"` // a list of access_logs AccessLogs []string `protobuf:"bytes,2,rep,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` // a list of error_logs @@ -1693,11 +1693,11 @@ func (*NGINXRuntimeInfo) Descriptor() ([]byte, []int) { return file_mpi_v1_command_proto_rawDescGZIP(), []int{24} } -func (x *NGINXRuntimeInfo) GetStubStatus() string { +func (x *NGINXRuntimeInfo) GetStubStatus() *APIDetails { if x != nil { return x.StubStatus } - return "" + return nil } func (x *NGINXRuntimeInfo) GetAccessLogs() []string { @@ -1734,8 +1734,8 @@ type NGINXPlusRuntimeInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // the stub status API URL - StubStatus string `protobuf:"bytes,1,opt,name=stub_status,json=stubStatus,proto3" json:"stub_status,omitempty"` + // the stub status API details + StubStatus *APIDetails `protobuf:"bytes,1,opt,name=stub_status,json=stubStatus,proto3" json:"stub_status,omitempty"` // a list of access_logs AccessLogs []string `protobuf:"bytes,2,rep,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` // a list of error_logs @@ -1744,8 +1744,8 @@ type NGINXPlusRuntimeInfo struct { LoadableModules []string `protobuf:"bytes,4,rep,name=loadable_modules,json=loadableModules,proto3" json:"loadable_modules,omitempty"` // List of NGINX dynamic modules. DynamicModules []string `protobuf:"bytes,5,rep,name=dynamic_modules,json=dynamicModules,proto3" json:"dynamic_modules,omitempty"` - // the plus API location - PlusApi string `protobuf:"bytes,6,opt,name=plus_api,json=plusApi,proto3" json:"plus_api,omitempty"` + // the plus API details + PlusApi *APIDetails `protobuf:"bytes,6,opt,name=plus_api,json=plusApi,proto3" json:"plus_api,omitempty"` } func (x *NGINXPlusRuntimeInfo) Reset() { @@ -1778,11 +1778,11 @@ func (*NGINXPlusRuntimeInfo) Descriptor() ([]byte, []int) { return file_mpi_v1_command_proto_rawDescGZIP(), []int{25} } -func (x *NGINXPlusRuntimeInfo) GetStubStatus() string { +func (x *NGINXPlusRuntimeInfo) GetStubStatus() *APIDetails { if x != nil { return x.StubStatus } - return "" + return nil } func (x *NGINXPlusRuntimeInfo) GetAccessLogs() []string { @@ -1813,10 +1813,65 @@ func (x *NGINXPlusRuntimeInfo) GetDynamicModules() []string { return nil } -func (x *NGINXPlusRuntimeInfo) GetPlusApi() string { +func (x *NGINXPlusRuntimeInfo) GetPlusApi() *APIDetails { if x != nil { return x.PlusApi } + return nil +} + +type APIDetails struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the API location directive + Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` + // the API listen directive + Listen string `protobuf:"bytes,2,opt,name=listen,proto3" json:"listen,omitempty"` +} + +func (x *APIDetails) Reset() { + *x = APIDetails{} + mi := &file_mpi_v1_command_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *APIDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*APIDetails) ProtoMessage() {} + +func (x *APIDetails) ProtoReflect() protoreflect.Message { + mi := &file_mpi_v1_command_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use APIDetails.ProtoReflect.Descriptor instead. +func (*APIDetails) Descriptor() ([]byte, []int) { + return file_mpi_v1_command_proto_rawDescGZIP(), []int{26} +} + +func (x *APIDetails) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +func (x *APIDetails) GetListen() string { + if x != nil { + return x.Listen + } return "" } @@ -1829,7 +1884,7 @@ type InstanceAction struct { func (x *InstanceAction) Reset() { *x = InstanceAction{} - mi := &file_mpi_v1_command_proto_msgTypes[26] + mi := &file_mpi_v1_command_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1841,7 +1896,7 @@ func (x *InstanceAction) String() string { func (*InstanceAction) ProtoMessage() {} func (x *InstanceAction) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[26] + mi := &file_mpi_v1_command_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1854,7 +1909,7 @@ func (x *InstanceAction) ProtoReflect() protoreflect.Message { // Deprecated: Use InstanceAction.ProtoReflect.Descriptor instead. func (*InstanceAction) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{26} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{27} } // This contains a series of NGINX Agent configurations @@ -1879,7 +1934,7 @@ type AgentConfig struct { func (x *AgentConfig) Reset() { *x = AgentConfig{} - mi := &file_mpi_v1_command_proto_msgTypes[27] + mi := &file_mpi_v1_command_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1891,7 +1946,7 @@ func (x *AgentConfig) String() string { func (*AgentConfig) ProtoMessage() {} func (x *AgentConfig) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[27] + mi := &file_mpi_v1_command_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1904,7 +1959,7 @@ func (x *AgentConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentConfig.ProtoReflect.Descriptor instead. func (*AgentConfig) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{27} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{28} } func (x *AgentConfig) GetCommand() *CommandServer { @@ -1965,7 +2020,7 @@ type CommandServer struct { func (x *CommandServer) Reset() { *x = CommandServer{} - mi := &file_mpi_v1_command_proto_msgTypes[28] + mi := &file_mpi_v1_command_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1977,7 +2032,7 @@ func (x *CommandServer) String() string { func (*CommandServer) ProtoMessage() {} func (x *CommandServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[28] + mi := &file_mpi_v1_command_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1990,7 +2045,7 @@ func (x *CommandServer) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandServer.ProtoReflect.Descriptor instead. func (*CommandServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{28} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{29} } func (x *CommandServer) GetServer() *ServerSettings { @@ -2023,7 +2078,7 @@ type MetricsServer struct { func (x *MetricsServer) Reset() { *x = MetricsServer{} - mi := &file_mpi_v1_command_proto_msgTypes[29] + mi := &file_mpi_v1_command_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2035,7 +2090,7 @@ func (x *MetricsServer) String() string { func (*MetricsServer) ProtoMessage() {} func (x *MetricsServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[29] + mi := &file_mpi_v1_command_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2048,7 +2103,7 @@ func (x *MetricsServer) ProtoReflect() protoreflect.Message { // Deprecated: Use MetricsServer.ProtoReflect.Descriptor instead. func (*MetricsServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{29} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{30} } // The file settings associated with file server for configurations @@ -2060,7 +2115,7 @@ type FileServer struct { func (x *FileServer) Reset() { *x = FileServer{} - mi := &file_mpi_v1_command_proto_msgTypes[30] + mi := &file_mpi_v1_command_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2072,7 +2127,7 @@ func (x *FileServer) String() string { func (*FileServer) ProtoMessage() {} func (x *FileServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[30] + mi := &file_mpi_v1_command_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2085,7 +2140,7 @@ func (x *FileServer) ProtoReflect() protoreflect.Message { // Deprecated: Use FileServer.ProtoReflect.Descriptor instead. func (*FileServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{30} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{31} } var File_mpi_v1_command_proto protoreflect.FileDescriptor @@ -2325,33 +2380,10 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 0x6c, 0x73, 0x22, 0x2e, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x49, 0x64, 0x22, 0xa2, 0x02, 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, - 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, - 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, - 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, - 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, - 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, - 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, - 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, - 0x6f, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, - 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, - 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x9c, 0x03, 0x0a, 0x14, 0x4e, 0x47, 0x49, 0x4e, - 0x58, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x20, 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, - 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, + 0x49, 0x64, 0x22, 0xdb, 0x01, 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1d, 0x0a, @@ -2362,69 +2394,83 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, - 0x12, 0x74, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, - 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, - 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x07, 0x70, - 0x6c, 0x75, 0x73, 0x41, 0x70, 0x69, 0x22, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x02, 0x0a, 0x0b, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x66, 0x69, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x04, 0x66, 0x69, - 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, - 0x2e, 0x0a, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, - 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, - 0x90, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x28, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x03, 0x74, - 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x2e, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x74, - 0x6c, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x32, 0x87, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, - 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, - 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, - 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, - 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x24, - 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, - 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x6d, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x8e, 0x02, 0x0a, 0x14, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x75, + 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x29, + 0x0a, 0x10, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, + 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, + 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x70, 0x6c, 0x75, 0x73, 0x41, 0x70, + 0x69, 0x22, 0x40, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x02, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, + 0x2f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x90, 0x01, 0x0a, + 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2e, + 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x28, + 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x22, + 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x32, 0x87, + 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x24, 0x2e, 0x6d, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x61, + 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, 0x06, 0x6d, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2440,7 +2486,7 @@ func file_mpi_v1_command_proto_rawDescGZIP() []byte { } var file_mpi_v1_command_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_mpi_v1_command_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_mpi_v1_command_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_mpi_v1_command_proto_goTypes = []any{ (InstanceHealth_InstanceHealthStatus)(0), // 0: mpi.v1.InstanceHealth.InstanceHealthStatus (InstanceMeta_InstanceType)(0), // 1: mpi.v1.InstanceMeta.InstanceType @@ -2470,73 +2516,77 @@ var file_mpi_v1_command_proto_goTypes = []any{ (*InstanceChild)(nil), // 25: mpi.v1.InstanceChild (*NGINXRuntimeInfo)(nil), // 26: mpi.v1.NGINXRuntimeInfo (*NGINXPlusRuntimeInfo)(nil), // 27: mpi.v1.NGINXPlusRuntimeInfo - (*InstanceAction)(nil), // 28: mpi.v1.InstanceAction - (*AgentConfig)(nil), // 29: mpi.v1.AgentConfig - (*CommandServer)(nil), // 30: mpi.v1.CommandServer - (*MetricsServer)(nil), // 31: mpi.v1.MetricsServer - (*FileServer)(nil), // 32: mpi.v1.FileServer - (*MessageMeta)(nil), // 33: mpi.v1.MessageMeta - (*CommandResponse)(nil), // 34: mpi.v1.CommandResponse - (*FileOverview)(nil), // 35: mpi.v1.FileOverview - (*structpb.Struct)(nil), // 36: google.protobuf.Struct - (*ServerSettings)(nil), // 37: mpi.v1.ServerSettings - (*AuthSettings)(nil), // 38: mpi.v1.AuthSettings - (*TLSSettings)(nil), // 39: mpi.v1.TLSSettings + (*APIDetails)(nil), // 28: mpi.v1.APIDetails + (*InstanceAction)(nil), // 29: mpi.v1.InstanceAction + (*AgentConfig)(nil), // 30: mpi.v1.AgentConfig + (*CommandServer)(nil), // 31: mpi.v1.CommandServer + (*MetricsServer)(nil), // 32: mpi.v1.MetricsServer + (*FileServer)(nil), // 33: mpi.v1.FileServer + (*MessageMeta)(nil), // 34: mpi.v1.MessageMeta + (*CommandResponse)(nil), // 35: mpi.v1.CommandResponse + (*FileOverview)(nil), // 36: mpi.v1.FileOverview + (*structpb.Struct)(nil), // 37: google.protobuf.Struct + (*ServerSettings)(nil), // 38: mpi.v1.ServerSettings + (*AuthSettings)(nil), // 39: mpi.v1.AuthSettings + (*TLSSettings)(nil), // 40: mpi.v1.TLSSettings } var file_mpi_v1_command_proto_depIdxs = []int32{ - 33, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 1: mpi.v1.CreateConnectionRequest.resource:type_name -> mpi.v1.Resource 21, // 2: mpi.v1.Resource.instances:type_name -> mpi.v1.Instance 4, // 3: mpi.v1.Resource.host_info:type_name -> mpi.v1.HostInfo 6, // 4: mpi.v1.Resource.container_info:type_name -> mpi.v1.ContainerInfo 5, // 5: mpi.v1.HostInfo.release_info:type_name -> mpi.v1.ReleaseInfo - 34, // 6: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse - 29, // 7: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig - 33, // 8: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta + 35, // 6: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse + 30, // 7: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig + 34, // 8: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 9: mpi.v1.UpdateDataPlaneStatusRequest.resource:type_name -> mpi.v1.Resource 0, // 10: mpi.v1.InstanceHealth.instance_health_status:type_name -> mpi.v1.InstanceHealth.InstanceHealthStatus - 33, // 11: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 11: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta 10, // 12: mpi.v1.UpdateDataPlaneHealthRequest.instance_healths:type_name -> mpi.v1.InstanceHealth - 33, // 13: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta - 34, // 14: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse - 33, // 15: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 13: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta + 35, // 14: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse + 34, // 15: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta 15, // 16: mpi.v1.ManagementPlaneRequest.status_request:type_name -> mpi.v1.StatusRequest 16, // 17: mpi.v1.ManagementPlaneRequest.health_request:type_name -> mpi.v1.HealthRequest 17, // 18: mpi.v1.ManagementPlaneRequest.config_apply_request:type_name -> mpi.v1.ConfigApplyRequest 18, // 19: mpi.v1.ManagementPlaneRequest.config_upload_request:type_name -> mpi.v1.ConfigUploadRequest 19, // 20: mpi.v1.ManagementPlaneRequest.action_request:type_name -> mpi.v1.APIActionRequest 20, // 21: mpi.v1.ManagementPlaneRequest.command_status_request:type_name -> mpi.v1.CommandStatusRequest - 35, // 22: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview - 35, // 23: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview + 36, // 22: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview + 36, // 23: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview 22, // 24: mpi.v1.Instance.instance_meta:type_name -> mpi.v1.InstanceMeta 23, // 25: mpi.v1.Instance.instance_config:type_name -> mpi.v1.InstanceConfig 24, // 26: mpi.v1.Instance.instance_runtime:type_name -> mpi.v1.InstanceRuntime 1, // 27: mpi.v1.InstanceMeta.instance_type:type_name -> mpi.v1.InstanceMeta.InstanceType - 28, // 28: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction - 29, // 29: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig + 29, // 28: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction + 30, // 29: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig 26, // 30: mpi.v1.InstanceRuntime.nginx_runtime_info:type_name -> mpi.v1.NGINXRuntimeInfo 27, // 31: mpi.v1.InstanceRuntime.nginx_plus_runtime_info:type_name -> mpi.v1.NGINXPlusRuntimeInfo 25, // 32: mpi.v1.InstanceRuntime.instance_children:type_name -> mpi.v1.InstanceChild - 30, // 33: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer - 31, // 34: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer - 32, // 35: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer - 36, // 36: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct - 37, // 37: mpi.v1.CommandServer.server:type_name -> mpi.v1.ServerSettings - 38, // 38: mpi.v1.CommandServer.auth:type_name -> mpi.v1.AuthSettings - 39, // 39: mpi.v1.CommandServer.tls:type_name -> mpi.v1.TLSSettings - 2, // 40: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest - 8, // 41: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest - 11, // 42: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest - 13, // 43: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse - 7, // 44: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse - 9, // 45: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse - 12, // 46: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse - 14, // 47: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest - 44, // [44:48] is the sub-list for method output_type - 40, // [40:44] is the sub-list for method input_type - 40, // [40:40] is the sub-list for extension type_name - 40, // [40:40] is the sub-list for extension extendee - 0, // [0:40] is the sub-list for field type_name + 28, // 33: mpi.v1.NGINXRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails + 28, // 34: mpi.v1.NGINXPlusRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails + 28, // 35: mpi.v1.NGINXPlusRuntimeInfo.plus_api:type_name -> mpi.v1.APIDetails + 31, // 36: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer + 32, // 37: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer + 33, // 38: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer + 37, // 39: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct + 38, // 40: mpi.v1.CommandServer.server:type_name -> mpi.v1.ServerSettings + 39, // 41: mpi.v1.CommandServer.auth:type_name -> mpi.v1.AuthSettings + 40, // 42: mpi.v1.CommandServer.tls:type_name -> mpi.v1.TLSSettings + 2, // 43: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest + 8, // 44: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest + 11, // 45: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest + 13, // 46: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse + 7, // 47: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse + 9, // 48: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse + 12, // 49: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse + 14, // 50: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest + 47, // [47:51] is the sub-list for method output_type + 43, // [43:47] is the sub-list for method input_type + 43, // [43:43] is the sub-list for extension type_name + 43, // [43:43] is the sub-list for extension extendee + 0, // [0:43] is the sub-list for field type_name } func init() { file_mpi_v1_command_proto_init() } @@ -2571,7 +2621,7 @@ func file_mpi_v1_command_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mpi_v1_command_proto_rawDesc, NumEnums: 2, - NumMessages: 31, + NumMessages: 32, NumExtensions: 0, NumServices: 1, }, diff --git a/api/grpc/mpi/v1/command.pb.validate.go b/api/grpc/mpi/v1/command.pb.validate.go index e23a11dae6..051f5904c7 100644 --- a/api/grpc/mpi/v1/command.pb.validate.go +++ b/api/grpc/mpi/v1/command.pb.validate.go @@ -3591,7 +3591,34 @@ func (m *NGINXRuntimeInfo) validate(all bool) error { var errors []error - // no validation rules for StubStatus + if all { + switch v := interface{}(m.GetStubStatus()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, NGINXRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, NGINXRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetStubStatus()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return NGINXRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + } + } + } if len(errors) > 0 { return NGINXRuntimeInfoMultiError(errors) @@ -3693,9 +3720,63 @@ func (m *NGINXPlusRuntimeInfo) validate(all bool) error { var errors []error - // no validation rules for StubStatus + if all { + switch v := interface{}(m.GetStubStatus()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, NGINXPlusRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, NGINXPlusRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetStubStatus()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return NGINXPlusRuntimeInfoValidationError{ + field: "StubStatus", + reason: "embedded message failed validation", + cause: err, + } + } + } - // no validation rules for PlusApi + if all { + switch v := interface{}(m.GetPlusApi()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, NGINXPlusRuntimeInfoValidationError{ + field: "PlusApi", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, NGINXPlusRuntimeInfoValidationError{ + field: "PlusApi", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetPlusApi()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return NGINXPlusRuntimeInfoValidationError{ + field: "PlusApi", + reason: "embedded message failed validation", + cause: err, + } + } + } if len(errors) > 0 { return NGINXPlusRuntimeInfoMultiError(errors) @@ -3777,6 +3858,109 @@ var _ interface { ErrorName() string } = NGINXPlusRuntimeInfoValidationError{} +// Validate checks the field values on APIDetails with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *APIDetails) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on APIDetails with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in APIDetailsMultiError, or +// nil if none found. +func (m *APIDetails) ValidateAll() error { + return m.validate(true) +} + +func (m *APIDetails) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Location + + // no validation rules for Listen + + if len(errors) > 0 { + return APIDetailsMultiError(errors) + } + + return nil +} + +// APIDetailsMultiError is an error wrapping multiple validation errors +// returned by APIDetails.ValidateAll() if the designated constraints aren't met. +type APIDetailsMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m APIDetailsMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m APIDetailsMultiError) AllErrors() []error { return m } + +// APIDetailsValidationError is the validation error returned by +// APIDetails.Validate if the designated constraints aren't met. +type APIDetailsValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e APIDetailsValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e APIDetailsValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e APIDetailsValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e APIDetailsValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e APIDetailsValidationError) ErrorName() string { return "APIDetailsValidationError" } + +// Error satisfies the builtin error interface +func (e APIDetailsValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sAPIDetails.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = APIDetailsValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = APIDetailsValidationError{} + // Validate checks the field values on InstanceAction with the rules defined in // the proto definition for this message. If any rules are violated, the first // error encountered is returned, or nil if there are no violations. diff --git a/api/grpc/mpi/v1/command.proto b/api/grpc/mpi/v1/command.proto index 8a5cd5f617..c179baaa87 100644 --- a/api/grpc/mpi/v1/command.proto +++ b/api/grpc/mpi/v1/command.proto @@ -264,12 +264,8 @@ message InstanceChild { // A set of runtime NGINX OSS settings message NGINXRuntimeInfo { - // the stub status API URL - string stub_status = 1 [(buf.validate.field).cel = { - id: "string.uri", - message: "value must be a valid URI or can be empty", - expression: "this == \'\' || this.isUri()" - }]; + // the stub status API details + APIDetails stub_status = 1; // a list of access_logs repeated string access_logs = 2; // a list of error_logs @@ -282,12 +278,8 @@ message NGINXRuntimeInfo { // A set of runtime NGINX Plus settings message NGINXPlusRuntimeInfo { - // the stub status API URL - string stub_status = 1 [(buf.validate.field).cel = { - id: "string.uri", - message: "value must be a valid URI or can be empty", - expression: "this == \'\' || this.isUri()" - }]; + // the stub status API details + APIDetails stub_status = 1; // a list of access_logs repeated string access_logs = 2; // a list of error_logs @@ -296,12 +288,15 @@ message NGINXPlusRuntimeInfo { repeated string loadable_modules = 4; // List of NGINX dynamic modules. repeated string dynamic_modules = 5; - // the plus API location - string plus_api = 6 [(buf.validate.field).cel = { - id: "string.uri", - message: "value must be a valid URI or can be empty", - expression: "this == \'\' || this.isUri()" - }]; + // the plus API details + APIDetails plus_api = 6; +} + +message APIDetails { + // the API location directive + string location = 1; + // the API listen directive + string listen = 2; } // A set of actions that can be performed on an instance diff --git a/docs/proto/protos.md b/docs/proto/protos.md index d926a358d9..6875763a04 100644 --- a/docs/proto/protos.md +++ b/docs/proto/protos.md @@ -40,6 +40,7 @@ - [mpi/v1/command.proto](#mpi_v1_command-proto) - [APIActionRequest](#mpi-v1-APIActionRequest) + - [APIDetails](#mpi-v1-APIDetails) - [AgentConfig](#mpi-v1-AgentConfig) - [CommandServer](#mpi-v1-CommandServer) - [CommandStatusRequest](#mpi-v1-CommandStatusRequest) @@ -599,6 +600,22 @@ Perform an associated API action on an instance + + +### APIDetails + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| location | [string](#string) | | the API location directive | +| listen | [string](#string) | | the API listen directive | + + + + + + ### AgentConfig @@ -929,12 +946,12 @@ A set of runtime NGINX Plus settings | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| stub_status | [string](#string) | | the stub status API URL | +| stub_status | [APIDetails](#mpi-v1-APIDetails) | | the stub status API details | | access_logs | [string](#string) | repeated | a list of access_logs | | error_logs | [string](#string) | repeated | a list of error_logs | | loadable_modules | [string](#string) | repeated | List of NGINX potentially loadable modules (installed but not loaded). | | dynamic_modules | [string](#string) | repeated | List of NGINX dynamic modules. | -| plus_api | [string](#string) | | the plus API location | +| plus_api | [APIDetails](#mpi-v1-APIDetails) | | the plus API details | @@ -949,7 +966,7 @@ A set of runtime NGINX OSS settings | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| stub_status | [string](#string) | | the stub status API URL | +| stub_status | [APIDetails](#mpi-v1-APIDetails) | | the stub status API details | | access_logs | [string](#string) | repeated | a list of access_logs | | error_logs | [string](#string) | repeated | a list of error_logs | | loadable_modules | [string](#string) | repeated | List of NGINX potentially loadable modules (installed but not loaded). | diff --git a/go.mod b/go.mod index 78b1b20f06..8481ed0fe2 100644 --- a/go.mod +++ b/go.mod @@ -36,14 +36,13 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/testbed v0.114.0 github.com/shirou/gopsutil/v4 v4.24.10 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/testcontainers/testcontainers-go v0.34.0 github.com/trivago/grok v1.0.0 go.opentelemetry.io/collector/component v0.114.0 go.opentelemetry.io/collector/component/componenttest v0.114.0 go.opentelemetry.io/collector/config/confighttp v0.114.0 go.opentelemetry.io/collector/config/configtelemetry v0.114.0 - go.opentelemetry.io/collector/config/configtls v1.20.0 go.opentelemetry.io/collector/confmap v1.20.0 go.opentelemetry.io/collector/confmap/provider/envprovider v1.20.0 go.opentelemetry.io/collector/confmap/provider/fileprovider v1.20.0 @@ -233,6 +232,7 @@ require ( go.opentelemetry.io/collector/config/confignet v1.20.0 // indirect go.opentelemetry.io/collector/config/configopaque v1.20.0 // indirect go.opentelemetry.io/collector/config/configretry v1.20.0 // indirect + go.opentelemetry.io/collector/config/configtls v1.20.0 // indirect go.opentelemetry.io/collector/config/internal v0.114.0 // indirect go.opentelemetry.io/collector/connector/connectorprofiles v0.114.0 // indirect go.opentelemetry.io/collector/connector/connectortest v0.114.0 // indirect diff --git a/go.sum b/go.sum index 2f7075d330..5a643b5455 100644 --- a/go.sum +++ b/go.sum @@ -573,8 +573,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo= diff --git a/internal/collector/nginxossreceiver/README.md b/internal/collector/nginxossreceiver/README.md index c80c890386..29faea3762 100644 --- a/internal/collector/nginxossreceiver/README.md +++ b/internal/collector/nginxossreceiver/README.md @@ -16,8 +16,10 @@ You must also configure an access log as well. Please see [Setting Up the Access ### Receiver Config The following settings are required: - -- `endpoint` (default: `http://localhost:80/status`): The URL of the NGINX status endpoint +- `api_details`: Details for the NGINX status endpoint. + - `url`: (default: `http://localhost:80/status`): The URL of the NGINX status endpoint. + - `listen`: (default: `localhost:80`): The listen directive of the NGINX status endpoint. + - `location`: (default: `/status`): The location directive of the NGINX status endpoint. The following settings are optional: @@ -34,7 +36,10 @@ Example: ```yaml receivers: nginx: - endpoint: "http://localhost:80/status" + api_details: + url: "http://localhost:80/status" + listen: "localhost:80" + location: "/status" collection_interval: 10s access_logs: - log_format: "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" \"$http_x_forwarded_for\"\"$upstream_cache_status\"" diff --git a/internal/collector/nginxossreceiver/internal/config/config.go b/internal/collector/nginxossreceiver/internal/config/config.go index 5d8db53dae..73f5676065 100644 --- a/internal/collector/nginxossreceiver/internal/config/config.go +++ b/internal/collector/nginxossreceiver/internal/config/config.go @@ -22,11 +22,18 @@ const ( type Config struct { confighttp.ClientConfig `mapstructure:",squash"` + APIDetails APIDetails `mapstructure:"api_details"` AccessLogs []AccessLog `mapstructure:"access_logs"` MetricsBuilderConfig metadata.MetricsBuilderConfig `mapstructure:",squash"` scraperhelper.ControllerConfig `mapstructure:",squash"` } +type APIDetails struct { + URL string `mapstructure:"url"` + Listen string `mapstructure:"listen"` + Location string `mapstructure:"location"` +} + type AccessLog struct { LogFormat string `mapstructure:"log_format"` FilePath string `mapstructure:"file_path"` @@ -40,10 +47,14 @@ func CreateDefaultConfig() component.Config { return &Config{ ControllerConfig: cfg, ClientConfig: confighttp.ClientConfig{ - Endpoint: "http://localhost:80/status", - Timeout: defaultClientTimeout, + Timeout: defaultClientTimeout, }, MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), AccessLogs: []AccessLog{}, + APIDetails: APIDetails{ + URL: "http://localhost:80/status", + Listen: "localhost:80", + Location: "status", + }, } } diff --git a/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper.go b/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper.go index 6ca9ce021d..38779570b4 100644 --- a/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper.go +++ b/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper.go @@ -7,7 +7,9 @@ package stubstatus import ( "context" + "net" "net/http" + "strings" "time" "github.com/nginxinc/nginx-prometheus-exporter/client" @@ -55,10 +57,14 @@ func (s *NginxStubStatusScraper) ID() component.ID { return component.NewID(metadata.Type) } -func (s *NginxStubStatusScraper) Start(ctx context.Context, host component.Host) error { - httpClient, err := s.cfg.ToClient(ctx, host, s.settings.TelemetrySettings) - if err != nil { - return err +func (s *NginxStubStatusScraper) Start(_ context.Context, _ component.Host) error { + httpClient := http.DefaultClient + if strings.HasPrefix(s.cfg.APIDetails.Listen, "unix:") { + httpClient.Transport = &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", strings.TrimPrefix(s.cfg.APIDetails.Listen, "unix:")) + }, + } } s.httpClient = httpClient @@ -72,7 +78,7 @@ func (s *NginxStubStatusScraper) Shutdown(_ context.Context) error { func (s *NginxStubStatusScraper) Scrape(context.Context) (pmetric.Metrics, error) { // Init client in scrape method in case there are transient errors in the constructor. if s.client == nil { - s.client = client.NewNginxClient(s.httpClient, s.cfg.ClientConfig.Endpoint) + s.client = client.NewNginxClient(s.httpClient, s.cfg.APIDetails.URL) } stats, err := s.client.GetStubStats() diff --git a/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper_test.go b/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper_test.go index 6c34c86092..9afff68c33 100644 --- a/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper_test.go +++ b/internal/collector/nginxossreceiver/internal/scraper/stubstatus/stub_status_scraper_test.go @@ -18,8 +18,6 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" - "go.opentelemetry.io/collector/config/confighttp" - "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/receiver/receivertest" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden" @@ -33,7 +31,7 @@ func TestStubStatusScraper(t *testing.T) { defer nginxMock.Close() cfg, ok := config.CreateDefaultConfig().(*config.Config) assert.True(t, ok) - cfg.Endpoint = nginxMock.URL + "/status" + cfg.APIDetails.URL = nginxMock.URL + "/status" require.NoError(t, component.ValidateConfig(cfg)) stubStatusScraper := NewScraper(receivertest.NewNopSettings(), cfg) @@ -68,8 +66,10 @@ func TestStubStatusScraperError(t *testing.T) { })) t.Run("404", func(t *testing.T) { sc := NewScraper(receivertest.NewNopSettings(), &config.Config{ - ClientConfig: confighttp.ClientConfig{ - Endpoint: nginxMock.URL + "/badpath", + APIDetails: config.APIDetails{ + URL: nginxMock.URL + "/badpath", + Listen: "", + Location: "", }, }) err := sc.Start(context.Background(), componenttest.NewNopHost()) @@ -80,8 +80,10 @@ func TestStubStatusScraperError(t *testing.T) { t.Run("parse error", func(t *testing.T) { sc := NewScraper(receivertest.NewNopSettings(), &config.Config{ - ClientConfig: confighttp.ClientConfig{ - Endpoint: nginxMock.URL + "/status", + APIDetails: config.APIDetails{ + URL: nginxMock.URL + "/status", + Listen: "", + Location: "", }, }) err := sc.Start(context.Background(), componenttest.NewNopHost()) @@ -92,21 +94,6 @@ func TestStubStatusScraperError(t *testing.T) { nginxMock.Close() } -func TestScraperFailedStart(t *testing.T) { - sc := NewScraper(receivertest.NewNopSettings(), &config.Config{ - ClientConfig: confighttp.ClientConfig{ - Endpoint: "localhost:8080", - TLSSetting: configtls.ClientConfig{ - Config: configtls.Config{ - CAFile: "/non/existent", - }, - }, - }, - }) - err := sc.Start(context.Background(), componenttest.NewNopHost()) - require.Error(t, err) -} - func newMockServer(t *testing.T) *httptest.Server { t.Helper() return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { diff --git a/internal/collector/nginxplusreceiver/README.md b/internal/collector/nginxplusreceiver/README.md index 615844fce8..a3f222c0db 100644 --- a/internal/collector/nginxplusreceiver/README.md +++ b/internal/collector/nginxplusreceiver/README.md @@ -13,7 +13,12 @@ Please see [ngx_http_api_module](https://nginx.org/en/docs/http/ngx_http_api_mod The following settings are required: -- `endpoint` (default: `http://localhost:80/api`): The URL of the NGINX Plus API endpoint + +The following settings are required: +- `api_details`: Details for the NGINX Plus API endpoint. + - `url`: (default: `http://localhost:80/api`): The URL of the NGINX Plus API endpoint. + - `listen`: (default: `localhost:80`): The listen directive of the NGINX Plus API endpoint. + - `location`: (default: `/api`): The location directive of the NGINX Plus API endpoint. The following settings are optional: @@ -26,6 +31,9 @@ Example: ```yaml receivers: nginxplus: - endpoint: "http://localhost:80/api" + api_details: + url: "http://localhost:80/api" + listen: "localhost:80" + location: "/api" collection_interval: 10s ``` diff --git a/internal/collector/nginxplusreceiver/config.go b/internal/collector/nginxplusreceiver/config.go index 2297f5534e..ece51812a0 100644 --- a/internal/collector/nginxplusreceiver/config.go +++ b/internal/collector/nginxplusreceiver/config.go @@ -8,6 +8,8 @@ import ( "errors" "time" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -18,13 +20,20 @@ const defaultCollectInterval = 10 * time.Second type Config struct { confighttp.ClientConfig `mapstructure:",squash"` + APIDetails APIDetails `mapstructure:"api_details"` MetricsBuilderConfig metadata.MetricsBuilderConfig `mapstructure:",squash"` scraperhelper.ControllerConfig `mapstructure:",squash"` } +type APIDetails struct { + URL string `mapstructure:"url"` + Listen string `mapstructure:"listen"` + Location string `mapstructure:"location"` +} + // Validate checks if the receiver configuration is valid func (cfg *Config) Validate() error { - if cfg.Endpoint == "" { + if cfg.APIDetails.URL == "" { return errors.New("endpoint cannot be empty for nginxplusreceiver") } @@ -34,3 +43,22 @@ func (cfg *Config) Validate() error { return nil } + +// nolint: ireturn +func createDefaultConfig() component.Config { + cfg := scraperhelper.NewDefaultControllerConfig() + cfg.CollectionInterval = defaultCollectInterval + + return &Config{ + ControllerConfig: cfg, + ClientConfig: confighttp.ClientConfig{ + Timeout: defaultTimeout, + }, + APIDetails: APIDetails{ + URL: "http://localhost:80/api", + Listen: "localhost:80", + Location: "/api", + }, + MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), + } +} diff --git a/internal/collector/nginxplusreceiver/factory.go b/internal/collector/nginxplusreceiver/factory.go index fac1e8b1e1..0e5157e430 100644 --- a/internal/collector/nginxplusreceiver/factory.go +++ b/internal/collector/nginxplusreceiver/factory.go @@ -11,7 +11,6 @@ import ( "time" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" @@ -29,21 +28,6 @@ func NewFactory() receiver.Factory { receiver.WithMetrics(createMetricsReceiver, metadata.MetricsStability)) } -// nolint: ireturn -func createDefaultConfig() component.Config { - cfg := scraperhelper.NewDefaultControllerConfig() - cfg.CollectionInterval = defaultCollectInterval - - return &Config{ - ControllerConfig: cfg, - ClientConfig: confighttp.ClientConfig{ - Endpoint: "http://localhost:80/api", - Timeout: defaultTimeout, - }, - MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), - } -} - // nolint: ireturn func createMetricsReceiver( ctx context.Context, diff --git a/internal/collector/nginxplusreceiver/scraper.go b/internal/collector/nginxplusreceiver/scraper.go index e51b918e7a..4911f49b5e 100644 --- a/internal/collector/nginxplusreceiver/scraper.go +++ b/internal/collector/nginxplusreceiver/scraper.go @@ -7,7 +7,10 @@ package nginxplusreceiver import ( "context" "fmt" + "net" + "net/http" "strconv" + "strings" "time" "go.uber.org/zap" @@ -43,14 +46,20 @@ func newNginxPlusScraper( settings receiver.Settings, cfg *Config, ) (*nginxPlusScraper, error) { + endpoint := strings.TrimPrefix(cfg.APIDetails.URL, "unix:") logger := settings.Logger logger.Info("Creating NGINX Plus scraper") + httpClient := http.DefaultClient mb := metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings) rb := mb.NewResourceBuilder() - plusClient, err := plusapi.NewNginxClient(cfg.Endpoint, - plusapi.WithMaxAPIVersion(), + if strings.HasPrefix(cfg.APIDetails.Listen, "unix:") { + httpClient = socketClient(strings.TrimPrefix(cfg.APIDetails.Listen, "unix:")) + } + + plusClient, err := plusapi.NewNginxClient(endpoint, + plusapi.WithMaxAPIVersion(), plusapi.WithHTTPClient(httpClient), ) if err != nil { return nil, err @@ -994,6 +1003,16 @@ func (nps *nginxPlusScraper) recordCacheMetrics(stats *plusapi.Stats, now pcommo } } +func socketClient(socketPath string) *http.Client { + return &http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", socketPath) + }, + }, + } +} + func (nps *nginxPlusScraper) Shutdown(ctx context.Context) error { return nil } diff --git a/internal/collector/nginxplusreceiver/scraper_test.go b/internal/collector/nginxplusreceiver/scraper_test.go index a10d1117af..e60ec747bf 100644 --- a/internal/collector/nginxplusreceiver/scraper_test.go +++ b/internal/collector/nginxplusreceiver/scraper_test.go @@ -24,7 +24,7 @@ func TestScraper(t *testing.T) { cfg, ok := createDefaultConfig().(*Config) assert.True(t, ok) - cfg.Endpoint = nginxPlusMock.URL + "/api" + cfg.APIDetails.URL = nginxPlusMock.URL + "/api" require.NoError(t, component.ValidateConfig(cfg)) scraper, err := newNginxPlusScraper(receivertest.NewNopSettings(), cfg) diff --git a/internal/collector/otel_collector_plugin.go b/internal/collector/otel_collector_plugin.go index 76a821b322..e91fbcee5e 100644 --- a/internal/collector/otel_collector_plugin.go +++ b/internal/collector/otel_collector_plugin.go @@ -371,25 +371,33 @@ func (oc *Collector) restartCollector(ctx context.Context) { func (oc *Collector) checkForNewNginxReceivers(nginxConfigContext *model.NginxConfigContext) bool { nginxReceiverFound, reloadCollector := oc.updateExistingNginxPlusReceiver(nginxConfigContext) - if !nginxReceiverFound && nginxConfigContext.PlusAPI != "" { + if !nginxReceiverFound && nginxConfigContext.PlusAPI.URL != "" { oc.config.Collector.Receivers.NginxPlusReceivers = append( oc.config.Collector.Receivers.NginxPlusReceivers, config.NginxPlusReceiver{ InstanceID: nginxConfigContext.InstanceID, - PlusAPI: nginxConfigContext.PlusAPI, + PlusAPI: config.APIDetails{ + URL: nginxConfigContext.PlusAPI.URL, + Listen: nginxConfigContext.PlusAPI.Listen, + Location: nginxConfigContext.PlusAPI.Location, + }, }, ) reloadCollector = true - } else if nginxConfigContext.PlusAPI == "" { + } else if nginxConfigContext.PlusAPI.URL == "" { nginxReceiverFound, reloadCollector = oc.updateExistingNginxOSSReceiver(nginxConfigContext) - if !nginxReceiverFound && nginxConfigContext.StubStatus != "" { + if !nginxReceiverFound && nginxConfigContext.StubStatus.URL != "" { oc.config.Collector.Receivers.NginxReceivers = append( oc.config.Collector.Receivers.NginxReceivers, config.NginxReceiver{ InstanceID: nginxConfigContext.InstanceID, - StubStatus: nginxConfigContext.StubStatus, + StubStatus: config.APIDetails{ + URL: nginxConfigContext.StubStatus.URL, + Listen: nginxConfigContext.StubStatus.Listen, + Location: nginxConfigContext.StubStatus.Location, + }, AccessLogs: toConfigAccessLog(nginxConfigContext.AccessLogs), }, ) @@ -408,13 +416,13 @@ func (oc *Collector) updateExistingNginxPlusReceiver( if nginxPlusReceiver.InstanceID == nginxConfigContext.InstanceID { nginxReceiverFound = true - if nginxPlusReceiver.PlusAPI != nginxConfigContext.PlusAPI { + if nginxPlusReceiver.PlusAPI.URL != nginxConfigContext.PlusAPI.URL { oc.config.Collector.Receivers.NginxPlusReceivers = append( oc.config.Collector.Receivers.NginxPlusReceivers[:index], oc.config.Collector.Receivers.NginxPlusReceivers[index+1:]..., ) - if nginxConfigContext.PlusAPI != "" { - nginxPlusReceiver.PlusAPI = nginxConfigContext.PlusAPI + if nginxConfigContext.PlusAPI.URL != "" { + nginxPlusReceiver.PlusAPI.URL = nginxConfigContext.PlusAPI.URL oc.config.Collector.Receivers.NginxPlusReceivers = append( oc.config.Collector.Receivers.NginxPlusReceivers, nginxPlusReceiver, @@ -444,8 +452,12 @@ func (oc *Collector) updateExistingNginxOSSReceiver( oc.config.Collector.Receivers.NginxReceivers[:index], oc.config.Collector.Receivers.NginxReceivers[index+1:]..., ) - if nginxConfigContext.StubStatus != "" { - nginxReceiver.StubStatus = nginxConfigContext.StubStatus + if nginxConfigContext.StubStatus.URL != "" { + nginxReceiver.StubStatus = config.APIDetails{ + URL: nginxConfigContext.StubStatus.URL, + Listen: nginxConfigContext.StubStatus.Listen, + Location: nginxConfigContext.StubStatus.Location, + } nginxReceiver.AccessLogs = toConfigAccessLog(nginxConfigContext.AccessLogs) oc.config.Collector.Receivers.NginxReceivers = append( oc.config.Collector.Receivers.NginxReceivers, @@ -490,7 +502,7 @@ func (oc *Collector) updateResourceAttributes( } func isOSSReceiverChanged(nginxReceiver config.NginxReceiver, nginxConfigContext *model.NginxConfigContext) bool { - return nginxReceiver.StubStatus != nginxConfigContext.StubStatus || + return nginxReceiver.StubStatus.URL != nginxConfigContext.StubStatus.URL || len(nginxReceiver.AccessLogs) != len(nginxConfigContext.AccessLogs) } diff --git a/internal/collector/otel_collector_plugin_test.go b/internal/collector/otel_collector_plugin_test.go index 002df2c8ec..d686603f9b 100644 --- a/internal/collector/otel_collector_plugin_test.go +++ b/internal/collector/otel_collector_plugin_test.go @@ -172,7 +172,11 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { Topic: bus.NginxConfigUpdateTopic, Data: &model.NginxConfigContext{ InstanceID: "123", - PlusAPI: "", + PlusAPI: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, }, }, receivers: config.Receivers{ @@ -181,7 +185,11 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { NginxPlusReceivers: []config.NginxPlusReceiver{ { InstanceID: "123", - PlusAPI: "", + PlusAPI: config.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, }, }, }, @@ -192,7 +200,16 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { Topic: bus.NginxConfigUpdateTopic, Data: &model.NginxConfigContext{ InstanceID: "123", - StubStatus: "", + StubStatus: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, + PlusAPI: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, AccessLogs: []*model.AccessLog{ { Name: "/var/log/nginx/access.log", @@ -207,7 +224,11 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { NginxReceivers: []config.NginxReceiver{ { InstanceID: "123", - StubStatus: "", + StubStatus: config.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, AccessLogs: []config.AccessLog{ { FilePath: "/var/log/nginx/access.log", @@ -234,8 +255,13 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { conf.Collector.Receivers.OtlpReceivers = nil if len(test.receivers.NginxPlusReceivers) == 1 { - url := fmt.Sprintf("%s/api", nginxPlusMock.URL) - test.receivers.NginxPlusReceivers[0].PlusAPI = url + apiDetails := config.APIDetails{ + URL: fmt.Sprintf("%s/api", nginxPlusMock.URL), + Listen: "", + Location: "", + } + + test.receivers.NginxPlusReceivers[0].PlusAPI = apiDetails model, ok := test.message.Data.(*model.NginxConfigContext) if !ok { @@ -243,10 +269,16 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { t.Fail() } - model.PlusAPI = url + model.PlusAPI.URL = apiDetails.URL + model.PlusAPI.Listen = apiDetails.Listen + model.PlusAPI.Location = apiDetails.Location } else { - url := fmt.Sprintf("%s/stub_status", nginxPlusMock.URL) - test.receivers.NginxReceivers[0].StubStatus = url + apiDetails := config.APIDetails{ + URL: fmt.Sprintf("%s/stub_status", nginxPlusMock.URL), + Listen: "", + Location: "", + } + test.receivers.NginxReceivers[0].StubStatus = apiDetails model, ok := test.message.Data.(*model.NginxConfigContext) if !ok { @@ -254,7 +286,9 @@ func TestCollector_ProcessNginxConfigUpdateTopic(t *testing.T) { t.Fail() } - model.StubStatus = url + model.StubStatus.URL = apiDetails.URL + model.PlusAPI.Listen = apiDetails.Listen + model.PlusAPI.Location = apiDetails.Location } conf.Collector.Processors.Batch = nil @@ -448,7 +482,11 @@ func TestCollector_updateExistingNginxOSSReceiver(t *testing.T) { name: "Test 1: Existing NGINX Receiver", nginxConfigContext: &model.NginxConfigContext{ InstanceID: "123", - StubStatus: "http://new-test-host:8080/api", + StubStatus: &model.APIDetails{ + URL: "http://new-test-host:8080/api", + Listen: "", + Location: "", + }, AccessLogs: []*model.AccessLog{ { Name: "/etc/nginx/test.log", @@ -460,7 +498,11 @@ func TestCollector_updateExistingNginxOSSReceiver(t *testing.T) { NginxReceivers: []config.NginxReceiver{ { InstanceID: "123", - StubStatus: "http://test.com:8080/api", + StubStatus: config.APIDetails{ + URL: "http://test.com:8080/api", + Listen: "", + Location: "", + }, AccessLogs: []config.AccessLog{ { FilePath: "/etc/nginx/existing.log", @@ -474,7 +516,11 @@ func TestCollector_updateExistingNginxOSSReceiver(t *testing.T) { NginxReceivers: []config.NginxReceiver{ { InstanceID: "123", - StubStatus: "http://new-test-host:8080/api", + StubStatus: config.APIDetails{ + URL: "http://new-test-host:8080/api", + Listen: "", + Location: "", + }, AccessLogs: []config.AccessLog{ { FilePath: "/etc/nginx/test.log", @@ -489,13 +535,21 @@ func TestCollector_updateExistingNginxOSSReceiver(t *testing.T) { name: "Test 2: Removing NGINX Receiver", nginxConfigContext: &model.NginxConfigContext{ InstanceID: "123", - StubStatus: "", + StubStatus: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, }, existingReceivers: config.Receivers{ NginxReceivers: []config.NginxReceiver{ { InstanceID: "123", - StubStatus: "http://test.com:8080/api", + StubStatus: config.APIDetails{ + URL: "http://test.com:8080/api", + Listen: "", + Location: "", + }, }, }, }, @@ -537,13 +591,21 @@ func TestCollector_updateExistingNginxPlusReceiver(t *testing.T) { name: "Test 1: Existing NGINX Plus Receiver", nginxConfigContext: &model.NginxConfigContext{ InstanceID: "123", - PlusAPI: "http://new-test-host:8080/api", + PlusAPI: &model.APIDetails{ + URL: "http://new-test-host:8080/api", + Listen: "", + Location: "", + }, }, existingReceivers: config.Receivers{ NginxPlusReceivers: []config.NginxPlusReceiver{ { InstanceID: "123", - PlusAPI: "http://test.com:8080/api", + PlusAPI: config.APIDetails{ + URL: "http://test.com:8080/api", + Listen: "", + Location: "", + }, }, }, }, @@ -551,7 +613,11 @@ func TestCollector_updateExistingNginxPlusReceiver(t *testing.T) { NginxPlusReceivers: []config.NginxPlusReceiver{ { InstanceID: "123", - PlusAPI: "http://new-test-host:8080/api", + PlusAPI: config.APIDetails{ + URL: "http://new-test-host:8080/api", + Listen: "", + Location: "", + }, }, }, }, @@ -560,13 +626,21 @@ func TestCollector_updateExistingNginxPlusReceiver(t *testing.T) { name: "Test 2: Removing NGINX Plus Receiver", nginxConfigContext: &model.NginxConfigContext{ InstanceID: "123", - PlusAPI: "", + PlusAPI: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, }, existingReceivers: config.Receivers{ NginxPlusReceivers: []config.NginxPlusReceiver{ { InstanceID: "123", - PlusAPI: "http://test.com:8080/api", + PlusAPI: config.APIDetails{ + URL: "http://test.com:8080/api", + Listen: "", + Location: "", + }, }, }, }, diff --git a/internal/collector/otelcol.tmpl b/internal/collector/otelcol.tmpl index 12bdc36ef4..e91f11eb8d 100644 --- a/internal/collector/otelcol.tmpl +++ b/internal/collector/otelcol.tmpl @@ -59,7 +59,10 @@ receivers: {{- end }} {{- range .Receivers.NginxReceivers }} nginx/{{- .InstanceID -}}: - endpoint: "{{- .StubStatus -}}" + api_details: + url: "{{- .StubStatus.URL -}}" + listen: "{{- .StubStatus.Listen -}}" + location: "{{- .StubStatus.Location -}}" collection_interval: 10s {{- if gt (len .AccessLogs) 0 }} access_logs: @@ -71,7 +74,10 @@ receivers: {{- end }} {{- range .Receivers.NginxPlusReceivers }} nginxplus/{{- .InstanceID -}}: - endpoint: "{{- .PlusAPI -}}" + api_details: + url: "{{- .PlusAPI.URL -}}" + listen: "{{- .PlusAPI.Listen -}}" + location: "{{- .PlusAPI.Location -}}" collection_interval: 10s {{- end }} diff --git a/internal/collector/settings_test.go b/internal/collector/settings_test.go index baf29807fe..e7946d7ff0 100644 --- a/internal/collector/settings_test.go +++ b/internal/collector/settings_test.go @@ -77,7 +77,11 @@ func TestTemplateWrite(t *testing.T) { } cfg.Collector.Receivers.NginxReceivers = append(cfg.Collector.Receivers.NginxReceivers, config.NginxReceiver{ InstanceID: "123", - StubStatus: "http://localhost:80/status", + StubStatus: config.APIDetails{ + URL: "http://localhost:80/status", + Location: "", + Listen: "", + }, AccessLogs: []config.AccessLog{ { LogFormat: accessLogFormat, diff --git a/internal/config/config_test.go b/internal/config/config_test.go index ad58a7a287..9cfb9d36e6 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -354,7 +354,10 @@ func getAgentConfig() *Config { NginxReceivers: []NginxReceiver{ { InstanceID: "cd7b8911-c2c5-4daf-b311-dbead151d938", - StubStatus: "http://localhost:4321/status", + StubStatus: APIDetails{ + URL: "http://localhost:4321/status", + Listen: "", + }, AccessLogs: []AccessLog{ { LogFormat: accessLogFormat, diff --git a/internal/config/types.go b/internal/config/types.go index 3ad6809fba..f532dad376 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -174,18 +174,24 @@ type ( NginxReceiver struct { InstanceID string `yaml:"-" mapstructure:"instance_id"` - StubStatus string `yaml:"-" mapstructure:"stub_status"` + StubStatus APIDetails `yaml:"-" mapstructure:"api_details"` AccessLogs []AccessLog `yaml:"-" mapstructure:"access_logs"` } + APIDetails struct { + URL string `yaml:"-" mapstructure:"url"` + Listen string `yaml:"-" mapstructure:"listen"` + Location string `yaml:"-" mapstructure:"location"` + } + AccessLog struct { FilePath string `yaml:"-" mapstructure:"file_path"` LogFormat string `yaml:"-" mapstructure:"log_format"` } NginxPlusReceiver struct { - InstanceID string `yaml:"-" mapstructure:"instance_id"` - PlusAPI string `yaml:"-" mapstructure:"plus_api"` + InstanceID string `yaml:"-" mapstructure:"instance_id"` + PlusAPI APIDetails `yaml:"-" mapstructure:"api_details"` } HostMetrics struct { diff --git a/internal/model/config.go b/internal/model/config.go index 3f37428912..15f0bbfbdb 100644 --- a/internal/model/config.go +++ b/internal/model/config.go @@ -12,20 +12,32 @@ import ( ) type NginxConfigContext struct { - StubStatus string - PlusAPI string + StubStatus *APIDetails + PlusAPI *APIDetails InstanceID string Files []*v1.File AccessLogs []*AccessLog ErrorLogs []*ErrorLog } +type APIDetails struct { + URL string + Listen string + Location string +} + +// Complexity is 11, allowed is 10 +// nolint: revive, cyclop func (ncc *NginxConfigContext) Equal(otherNginxConfigContext *NginxConfigContext) bool { - if ncc.StubStatus != otherNginxConfigContext.StubStatus { + if ncc.StubStatus.URL != otherNginxConfigContext.StubStatus.URL || ncc.StubStatus.Listen != + otherNginxConfigContext.StubStatus.Listen || ncc.StubStatus.Location != + otherNginxConfigContext.StubStatus.Location { return false } - if ncc.PlusAPI != otherNginxConfigContext.PlusAPI { + if ncc.PlusAPI.URL != otherNginxConfigContext.PlusAPI.URL || ncc.PlusAPI.Listen != + otherNginxConfigContext.PlusAPI.Listen || ncc.PlusAPI.Location != + otherNginxConfigContext.PlusAPI.Location { return false } diff --git a/internal/model/config_test.go b/internal/model/config_test.go index eea285094f..0d7ea9069c 100644 --- a/internal/model/config_test.go +++ b/internal/model/config_test.go @@ -14,8 +14,14 @@ import ( ) var nginxConfigContext = &NginxConfigContext{ - StubStatus: "", - PlusAPI: "", + StubStatus: &APIDetails{ + URL: "", + Listen: "", + }, + PlusAPI: &APIDetails{ + URL: "", + Listen: "", + }, InstanceID: "12333", Files: []*mpi.File{ { @@ -42,10 +48,16 @@ func TestNginxConfigContext_Equal(t *testing.T) { nginxConfigContextWithSameValues := *nginxConfigContext nginxConfigContextWithDifferentStubStatus := *nginxConfigContext - nginxConfigContextWithDifferentStubStatus.StubStatus = "http://localhost:8080/stub_status" + nginxConfigContextWithDifferentStubStatus.StubStatus = &APIDetails{ + URL: "http://localhost:8080/stub_status", + Listen: "", + } nginxConfigContextWithDifferentPlusAPI := *nginxConfigContext - nginxConfigContextWithDifferentPlusAPI.PlusAPI = "http://localhost:8080/api" + nginxConfigContextWithDifferentPlusAPI.PlusAPI = &APIDetails{ + URL: "http://localhost:8080/api", + Listen: "", + } nginxConfigContextWithDifferentInstanceID := *nginxConfigContext nginxConfigContextWithDifferentInstanceID.InstanceID = "567" diff --git a/internal/watcher/instance/instance_watcher_service.go b/internal/watcher/instance/instance_watcher_service.go index a7aaec4c1c..fb64ecdc32 100644 --- a/internal/watcher/instance/instance_watcher_service.go +++ b/internal/watcher/instance/instance_watcher_service.go @@ -397,25 +397,23 @@ func (iw *InstanceWatcherService) updateNginxInstanceRuntime( if instanceType == mpi.InstanceMeta_INSTANCE_TYPE_NGINX_PLUS { nginxPlusRuntimeInfo := instance.GetInstanceRuntime().GetNginxPlusRuntimeInfo() - if !reflect.DeepEqual(nginxPlusRuntimeInfo.GetAccessLogs(), accessLogs) || - !reflect.DeepEqual(nginxPlusRuntimeInfo.GetErrorLogs(), errorLogs) || - nginxPlusRuntimeInfo.GetStubStatus() != nginxConfigContext.StubStatus || - nginxPlusRuntimeInfo.GetPlusApi() != nginxConfigContext.PlusAPI { + if nginxPlusRuntimeInfoEqual(nginxPlusRuntimeInfo, nginxConfigContext, accessLogs, errorLogs) { nginxPlusRuntimeInfo.AccessLogs = accessLogs nginxPlusRuntimeInfo.ErrorLogs = errorLogs - nginxPlusRuntimeInfo.StubStatus = nginxConfigContext.StubStatus - nginxPlusRuntimeInfo.PlusApi = nginxConfigContext.PlusAPI + nginxPlusRuntimeInfo.StubStatus.Listen = nginxConfigContext.StubStatus.Listen + nginxPlusRuntimeInfo.PlusApi.Listen = nginxConfigContext.PlusAPI.Listen + nginxPlusRuntimeInfo.StubStatus.Location = nginxConfigContext.StubStatus.Location + nginxPlusRuntimeInfo.PlusApi.Location = nginxConfigContext.PlusAPI.Location updatesRequired = true } } else { nginxRuntimeInfo := instance.GetInstanceRuntime().GetNginxRuntimeInfo() - if !reflect.DeepEqual(nginxRuntimeInfo.GetAccessLogs(), accessLogs) || - !reflect.DeepEqual(nginxRuntimeInfo.GetErrorLogs(), errorLogs) || - nginxRuntimeInfo.GetStubStatus() != nginxConfigContext.StubStatus { + if nginxRuntimeInfoEqual(nginxRuntimeInfo, nginxConfigContext, accessLogs, errorLogs) { nginxRuntimeInfo.AccessLogs = accessLogs nginxRuntimeInfo.ErrorLogs = errorLogs - nginxRuntimeInfo.StubStatus = nginxConfigContext.StubStatus + nginxRuntimeInfo.StubStatus.Location = nginxConfigContext.StubStatus.Location + nginxRuntimeInfo.StubStatus.Listen = nginxConfigContext.StubStatus.Listen updatesRequired = true } } @@ -423,6 +421,34 @@ func (iw *InstanceWatcherService) updateNginxInstanceRuntime( return updatesRequired } +func nginxPlusRuntimeInfoEqual(nginxPlusRuntimeInfo *mpi.NGINXPlusRuntimeInfo, + nginxConfigContext *model.NginxConfigContext, accessLogs, errorLogs []string, +) bool { + if !reflect.DeepEqual(nginxPlusRuntimeInfo.GetAccessLogs(), accessLogs) || + !reflect.DeepEqual(nginxPlusRuntimeInfo.GetErrorLogs(), errorLogs) || + nginxPlusRuntimeInfo.GetStubStatus().GetListen() != nginxConfigContext.StubStatus.Listen || + nginxPlusRuntimeInfo.GetPlusApi().GetListen() != nginxConfigContext.PlusAPI.Listen || + nginxPlusRuntimeInfo.GetStubStatus().GetLocation() != nginxConfigContext.StubStatus.Location || + nginxPlusRuntimeInfo.GetPlusApi().GetLocation() != nginxConfigContext.PlusAPI.Location { + return true + } + + return false +} + +func nginxRuntimeInfoEqual(nginxRuntimeInfo *mpi.NGINXRuntimeInfo, nginxConfigContext *model.NginxConfigContext, + accessLogs, errorLogs []string, +) bool { + if !reflect.DeepEqual(nginxRuntimeInfo.GetAccessLogs(), accessLogs) || + !reflect.DeepEqual(nginxRuntimeInfo.GetErrorLogs(), errorLogs) || + nginxRuntimeInfo.GetStubStatus().GetListen() != nginxConfigContext.StubStatus.Listen || + nginxRuntimeInfo.GetStubStatus().GetLocation() != nginxConfigContext.StubStatus.Location { + return true + } + + return false +} + func convertAccessLogs(accessLogs []*model.AccessLog) (logs []string) { for _, log := range accessLogs { logs = append(logs, log.Name) diff --git a/internal/watcher/instance/instance_watcher_service_test.go b/internal/watcher/instance/instance_watcher_service_test.go index fb6a0cf49f..f71ff3e988 100644 --- a/internal/watcher/instance/instance_watcher_service_test.go +++ b/internal/watcher/instance/instance_watcher_service_test.go @@ -168,7 +168,10 @@ func TestInstanceWatcherService_updateNginxInstanceRuntime(t *testing.T) { Name: "/usr/local/var/log/nginx/error.log", }, }, - StubStatus: "http://127.0.0.1:8081/api", + StubStatus: &model.APIDetails{ + URL: "http://127.0.0.1:8081/api", + Listen: "", + }, } nginxPlusConfigContext := &model.NginxConfigContext{ @@ -182,7 +185,14 @@ func TestInstanceWatcherService_updateNginxInstanceRuntime(t *testing.T) { Name: "/usr/local/var/log/nginx/error.log", }, }, - PlusAPI: "http://127.0.0.1:8081/api", + PlusAPI: &model.APIDetails{ + URL: "http://127.0.0.1:8081/api", + Listen: "", + }, + StubStatus: &model.APIDetails{ + URL: "http://127.0.0.1:8081/api", + Listen: "", + }, } tests := []struct { @@ -210,17 +220,23 @@ func TestInstanceWatcherService_updateNginxInstanceRuntime(t *testing.T) { GetNginxPlusRuntimeInfo().GetAccessLogs()[0]) assert.Equal(t, test.nginxConfigContext.ErrorLogs[0].Name, test.instance.GetInstanceRuntime(). GetNginxPlusRuntimeInfo().GetErrorLogs()[0]) - assert.Equal(t, test.nginxConfigContext.StubStatus, test.instance.GetInstanceRuntime(). - GetNginxPlusRuntimeInfo().GetStubStatus()) - assert.Equal(t, test.nginxConfigContext.PlusAPI, test.instance.GetInstanceRuntime(). - GetNginxPlusRuntimeInfo().GetPlusApi()) + assert.Equal(t, test.nginxConfigContext.StubStatus.Location, test.instance.GetInstanceRuntime(). + GetNginxPlusRuntimeInfo().GetStubStatus().GetLocation()) + assert.Equal(t, test.nginxConfigContext.PlusAPI.Location, test.instance.GetInstanceRuntime(). + GetNginxPlusRuntimeInfo().GetPlusApi().GetLocation()) + assert.Equal(t, test.nginxConfigContext.StubStatus.Listen, test.instance.GetInstanceRuntime(). + GetNginxPlusRuntimeInfo().GetStubStatus().GetListen()) + assert.Equal(t, test.nginxConfigContext.PlusAPI.Listen, test.instance.GetInstanceRuntime(). + GetNginxPlusRuntimeInfo().GetPlusApi().GetListen()) } else { assert.Equal(t, test.nginxConfigContext.AccessLogs[0].Name, test.instance.GetInstanceRuntime(). GetNginxRuntimeInfo().GetAccessLogs()[0]) assert.Equal(t, test.nginxConfigContext.ErrorLogs[0].Name, test.instance.GetInstanceRuntime(). GetNginxRuntimeInfo().GetErrorLogs()[0]) - assert.Equal(t, test.nginxConfigContext.StubStatus, test.instance.GetInstanceRuntime(). - GetNginxRuntimeInfo().GetStubStatus()) + assert.Equal(t, test.nginxConfigContext.StubStatus.Location, test.instance.GetInstanceRuntime(). + GetNginxRuntimeInfo().GetStubStatus().GetLocation()) + assert.Equal(t, test.nginxConfigContext.StubStatus.Listen, test.instance.GetInstanceRuntime(). + GetNginxRuntimeInfo().GetStubStatus().GetListen()) } }) } diff --git a/internal/watcher/instance/nginx_config_parser.go b/internal/watcher/instance/nginx_config_parser.go index cc7a2c9d48..34beb8a97c 100644 --- a/internal/watcher/instance/nginx_config_parser.go +++ b/internal/watcher/instance/nginx_config_parser.go @@ -35,6 +35,8 @@ const ( plusAPIDirective = "api" stubStatusAPIDirective = "stub_status" apiFormat = "http://%s%s" + unixStubStatusFormat = "http://config-status%s" + unixPlusAPIFormat = "http://nginx-plus-api%s" locationDirective = "location" ) @@ -47,8 +49,9 @@ type ( var _ nginxConfigParser = (*NginxConfigParser)(nil) type ( - crossplaneTraverseCallback = func(ctx context.Context, parent, current *crossplane.Directive) error - crossplaneTraverseCallbackStr = func(ctx context.Context, parent, current *crossplane.Directive) string + crossplaneTraverseCallback = func(ctx context.Context, parent, current *crossplane.Directive) error + crossplaneTraverseCallbackAPIDetails = func(ctx context.Context, parent, + current *crossplane.Directive, apiType string) *model.APIDetails ) func NewNginxConfigParser(agentConfig *config.Config) *NginxConfigParser { @@ -92,6 +95,16 @@ func (ncp *NginxConfigParser) createNginxConfigContext( ) (*model.NginxConfigContext, error) { nginxConfigContext := &model.NginxConfigContext{ InstanceID: instance.GetInstanceMeta().GetInstanceId(), + PlusAPI: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, + StubStatus: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, } rootDir := filepath.Dir(instance.GetInstanceRuntime().GetConfigPath()) @@ -129,16 +142,14 @@ func (ncp *NginxConfigParser) createNginxConfigContext( return nginxConfigContext, fmt.Errorf("traverse nginx config: %w", err) } - stubStatus := ncp.crossplaneConfigTraverseStr(ctx, &conf, ncp.stubStatusAPICallback) - if stubStatus != "" { + stubStatus := ncp.crossplaneConfigTraverseAPIDetails(ctx, &conf, ncp.apiCallback, stubStatusAPIDirective) + if stubStatus.URL != "" { nginxConfigContext.StubStatus = stubStatus } - if instance.GetInstanceMeta().GetInstanceType() == mpi.InstanceMeta_INSTANCE_TYPE_NGINX_PLUS { - plusAPIURL := ncp.crossplaneConfigTraverseStr(ctx, &conf, ncp.plusAPICallback) - if plusAPIURL != "" { - nginxConfigContext.PlusAPI = plusAPIURL - } + plusAPI := ncp.crossplaneConfigTraverseAPIDetails(ctx, &conf, ncp.apiCallback, plusAPIDirective) + if plusAPI.URL != "" { + nginxConfigContext.PlusAPI = plusAPI } fileMeta, err := files.FileMeta(conf.File) @@ -334,20 +345,25 @@ func (ncp *NginxConfigParser) crossplaneConfigTraverse( return nil } -func (ncp *NginxConfigParser) crossplaneConfigTraverseStr( +func (ncp *NginxConfigParser) crossplaneConfigTraverseAPIDetails( ctx context.Context, root *crossplane.Config, - callback crossplaneTraverseCallbackStr, -) string { + callback crossplaneTraverseCallbackAPIDetails, + apiType string, +) *model.APIDetails { stop := false - response := "" + response := &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + } for _, dir := range root.Parsed { - response = callback(ctx, nil, dir) - if response != "" { + response = callback(ctx, nil, dir, apiType) + if response.URL != "" { return response } - response = traverseStr(ctx, dir, callback, &stop) - if response != "" { + response = traverseAPIDetails(ctx, dir, callback, &stop, apiType) + if response.URL != "" { return response } } @@ -355,23 +371,32 @@ func (ncp *NginxConfigParser) crossplaneConfigTraverseStr( return response } -func traverseStr( +func traverseAPIDetails( ctx context.Context, root *crossplane.Directive, - callback crossplaneTraverseCallbackStr, + callback crossplaneTraverseCallbackAPIDetails, stop *bool, -) string { - response := "" + apiType string, +) *model.APIDetails { + response := &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + } if *stop { - return "" + return &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + } } for _, child := range root.Block { - response = callback(ctx, root, child) - if response != "" { + response = callback(ctx, root, child, apiType) + if response.URL != "" { *stop = true return response } - response = traverseStr(ctx, child, callback, stop) + response = traverseAPIDetails(ctx, child, callback, stop, apiType) if *stop { return response } @@ -404,39 +429,55 @@ func (ncp *NginxConfigParser) hasAdditionArguments(args []string) bool { return len(args) >= defaultNumberOfDirectiveArguments } -func (ncp *NginxConfigParser) stubStatusAPICallback(ctx context.Context, parent, current *crossplane.Directive) string { - urls := ncp.urlsForLocationDirective(parent, current, stubStatusAPIDirective) +func (ncp *NginxConfigParser) apiCallback(ctx context.Context, parent, + current *crossplane.Directive, apiType string, +) *model.APIDetails { + urls := ncp.urlsForLocationDirectiveAPIDetails(parent, current, apiType) if len(urls) > 0 { - slog.DebugContext(ctx, "Potential stub_status urls", "urls", urls) + slog.DebugContext(ctx, fmt.Sprintf("Potential %s urls", apiType), "urls", urls) } for _, url := range urls { - if ncp.pingStubStatusAPIEndpoint(ctx, url) { - slog.DebugContext(ctx, "Stub_status found", "url", url) + if ncp.pingAPIEndpoint(ctx, url, apiType) { + slog.DebugContext(ctx, fmt.Sprintf("%s found", apiType), "url", url) return url } - slog.DebugContext(ctx, "Stub_status is not reachable", "url", url) + slog.DebugContext(ctx, fmt.Sprintf("%s is not reachable", apiType), "url", url) } - return "" + return &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + } } -func (ncp *NginxConfigParser) pingStubStatusAPIEndpoint(ctx context.Context, statusAPI string) bool { - httpClient := http.Client{Timeout: ncp.agentConfig.Client.Timeout} +func (ncp *NginxConfigParser) pingAPIEndpoint(ctx context.Context, statusAPIDetail *model.APIDetails, + apiType string, +) bool { + httpClient := http.Client{} + listen := statusAPIDetail.Listen + statusAPI := statusAPIDetail.URL + + if strings.HasPrefix(listen, "unix:") { + httpClient = ncp.SocketClient(strings.TrimPrefix(listen, "unix:")) + } else { + httpClient = http.Client{Timeout: ncp.agentConfig.Client.Timeout} + } req, err := http.NewRequestWithContext(ctx, http.MethodGet, statusAPI, nil) if err != nil { - slog.WarnContext(ctx, "Unable to create Stub Status API GET request", "error", err) + slog.WarnContext(ctx, fmt.Sprintf("Unable to create %s API GET request", apiType), "error", err) return false } resp, err := httpClient.Do(req) if err != nil { - slog.WarnContext(ctx, "Unable to GET Stub Status from API request", "error", err) + slog.WarnContext(ctx, fmt.Sprintf("Unable to GET %s from API request", apiType), "error", err) return false } if resp.StatusCode != http.StatusOK { - slog.DebugContext(ctx, "Stub Status API responded with unexpected status code", "status_code", + slog.DebugContext(ctx, fmt.Sprintf("%s API responded with unexpected status code", apiType), "status_code", resp.StatusCode, "expected", http.StatusOK) return false @@ -444,7 +485,7 @@ func (ncp *NginxConfigParser) pingStubStatusAPIEndpoint(ctx context.Context, sta bodyBytes, err := io.ReadAll(resp.Body) if err != nil { - slog.WarnContext(ctx, "Unable to read Stub Status API response body", "error", err) + slog.WarnContext(ctx, fmt.Sprintf("Unable to read %s API response body", apiType), "error", err) return false } @@ -454,55 +495,13 @@ func (ncp *NginxConfigParser) pingStubStatusAPIEndpoint(ctx context.Context, sta // server accepts handled requests // 18 18 3266 // Reading: 0 Writing: 1 Waiting: 1 - body := string(bodyBytes) - defer resp.Body.Close() - - return strings.Contains(body, "Active connections") && strings.Contains(body, "server accepts handled requests") -} - -func (ncp *NginxConfigParser) plusAPICallback(ctx context.Context, parent, current *crossplane.Directive) string { - urls := ncp.urlsForLocationDirective(parent, current, plusAPIDirective) - if len(urls) > 0 { - slog.DebugContext(ctx, "Potential Plus API urls", "urls", urls) - } - - for _, url := range urls { - if ncp.pingPlusAPIEndpoint(ctx, url) { - slog.DebugContext(ctx, "Plus API found", "url", url) - return url - } - slog.DebugContext(ctx, "Plus API is not reachable", "url", url) - } - - return "" -} - -func (ncp *NginxConfigParser) pingPlusAPIEndpoint(ctx context.Context, statusAPI string) bool { - httpClient := http.Client{Timeout: ncp.agentConfig.Client.Timeout} - req, err := http.NewRequestWithContext(ctx, http.MethodGet, statusAPI, nil) - if err != nil { - slog.WarnContext(ctx, "Unable to create NGINX Plus API GET request", "error", err) - return false - } - resp, err := httpClient.Do(req) - if err != nil { - slog.WarnContext(ctx, "Unable to GET NGINX Plus API from API request", "error", err) - return false - } - - if resp.StatusCode != http.StatusOK { - slog.DebugContext(ctx, "NGINX Plus API responded with unexpected status code", "status_code", - resp.StatusCode, "expected", http.StatusOK) - return false - } + if apiType == stubStatusAPIDirective { + body := string(bodyBytes) + defer resp.Body.Close() - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - slog.WarnContext(ctx, "Unable to read NGINX Plus API response body", "error", err) - return false + return strings.Contains(body, "Active connections") && strings.Contains(body, "server accepts handled requests") } - // Expecting API to return the API versions in an array of positive integers // subset example: [ ... 6,7,8,9 ...] var responseBody []int @@ -516,11 +515,12 @@ func (ncp *NginxConfigParser) pingPlusAPIEndpoint(ctx context.Context, statusAPI return true } -func (ncp *NginxConfigParser) urlsForLocationDirective( +// nolint: revive +func (ncp *NginxConfigParser) urlsForLocationDirectiveAPIDetails( parent, current *crossplane.Directive, locationDirectiveName string, -) []string { - var urls []string +) []*model.APIDetails { + var urls []*model.APIDetails // process from the location block if current.Directive != locationDirective { return urls @@ -534,10 +534,28 @@ func (ncp *NginxConfigParser) urlsForLocationDirective( addresses := ncp.parseAddressesFromServerDirective(parent) for _, address := range addresses { + format := unixStubStatusFormat + + if locChild.Directive == plusAPIDirective { + format = unixPlusAPIFormat + } + path := ncp.parsePathFromLocationDirective(current) if locChild.Directive == locationDirectiveName { - urls = append(urls, fmt.Sprintf(apiFormat, address, path)) + if strings.HasPrefix(address, "unix:") { + urls = append(urls, &model.APIDetails{ + URL: fmt.Sprintf(format, path), + Listen: address, + Location: path, + }) + } else { + urls = append(urls, &model.APIDetails{ + URL: fmt.Sprintf(apiFormat, address, path), + Listen: address, + Location: path, + }) + } } } } @@ -633,3 +651,14 @@ func (ncp *NginxConfigParser) isPort(value string) bool { return err == nil && port >= 1 && port <= 65535 } + +func (ncp *NginxConfigParser) SocketClient(socketPath string) http.Client { + return http.Client{ + Timeout: ncp.agentConfig.Client.Timeout, + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", socketPath) + }, + }, + } +} diff --git a/internal/watcher/instance/nginx_config_parser_test.go b/internal/watcher/instance/nginx_config_parser_test.go index e58905b224..36f08c4a98 100644 --- a/internal/watcher/instance/nginx_config_parser_test.go +++ b/internal/watcher/instance/nginx_config_parser_test.go @@ -15,19 +15,20 @@ import ( "strings" "testing" + "github.com/google/go-cmp/cmp" + "github.com/nginx/agent/v3/internal/model" + "github.com/nginx/agent/v3/pkg/files" + "google.golang.org/protobuf/testing/protocmp" + "github.com/nginx/agent/v3/test/stub" - "github.com/google/go-cmp/cmp" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" - "github.com/nginx/agent/v3/pkg/files" testconfig "github.com/nginx/agent/v3/test/config" "github.com/nginx/agent/v3/test/helpers" modelHelpers "github.com/nginx/agent/v3/test/model" "github.com/nginx/agent/v3/test/protos" "github.com/nginx/agent/v3/test/types" crossplane "github.com/nginxinc/nginx-go-crossplane" - "google.golang.org/protobuf/testing/protocmp" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -242,6 +243,23 @@ var ( api; } }` + + testConf20 = `server { + listen unix:/var/run/nginx/nginx-status.sock; + location /stub_status { + stub_status; + } +} +` + testConf21 = `server { + listen unix:/var/run/nginx/nginx-plus-api.sock; + access_log off; + + location /api { + api write=on; + } + } +` ) func TestNginxConfigParser_Parse(t *testing.T) { @@ -312,7 +330,7 @@ func TestNginxConfigParser_Parse(t *testing.T) { result, parseError := nginxConfig.Parse(ctx, test.instance) require.NoError(t, parseError) - if diff := cmp.Diff(expectedConfigContext, result, protocmp.Transform()); diff != "" { + if diff := cmp.Diff(expectedConfigContext.AccessLogs, result.AccessLogs, protocmp.Transform()); diff != "" { t.Errorf("\n%v", diff) } }) @@ -365,140 +383,303 @@ func TestNginxConfigParser_sslCert(t *testing.T) { assert.Equal(t, certFile, sslCert.GetFileMeta().GetName()) } +// nolint: maintidx func TestNginxConfigParser_urlsForLocationDirective(t *testing.T) { tmpDir := t.TempDir() for _, tt := range []struct { + name string conf string - oss []string - plus []string + oss []*model.APIDetails + plus []*model.APIDetails }{ { - plus: []string{ - "http://127.0.0.1:80/api/", - "http://localhost:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, + { + URL: "http://localhost:80/api/", + Listen: "localhost:80", + Location: "/api/", + }, }, + name: "Test 1: listen localhost 80, allow 127.0.0.1 - Plus", conf: testConf01, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 2: listen *:80 - Plus", conf: testConf02, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 3: server_name _ - Plus", conf: testConf03, }, { - plus: []string{ - "http://127.0.0.1:8888/api/", - "http://status.internal.com:8888/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:8888/api/", + Listen: "127.0.0.1:8888", + Location: "/api/", + }, + { + URL: "http://status.internal.com:8888/api/", + Listen: "status.internal.com:8888", + Location: "/api/", + }, }, + name: "Test 4: server_name status.internal.com - Plus", conf: testConf04, }, { - plus: []string{ - "http://127.0.0.1:8080/privateapi", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:8080/privateapi", + Listen: "127.0.0.1:8080", + Location: "/privateapi", + }, }, + name: "Test 5: location /privateapi - Plus", conf: testConf05, }, { - plus: []string{ - "http://127.0.0.1:80/api/", - "http://[::1]:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, + { + URL: "http://[::1]:80/api/", + Listen: "[::1]:80", + Location: "/api/", + }, }, + name: "Test 6: listen [::]:80 default_server - Plus", conf: testConf06, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 7: listen 127.0.0.1, server_name _ - Plus", conf: testConf07, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 8: location = /api/, listen 127.0.0.1 - Plus", conf: testConf08, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 9: location = /api/ , listen 80 - Plus", conf: testConf09, }, { - plus: []string{ - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 10: listen :80 - Plus", conf: testConf10, }, { - plus: []string{ - "http://localhost:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://localhost:80/api/", + Listen: "localhost:80", + Location: "/api/", + }, }, + name: "Test 11: listen localhost - Plus", conf: testConf11, }, { - plus: []string{ - "http://[::1]:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://[::1]:80/api/", + Listen: "[::1]:80", + Location: "/api/", + }, }, + name: "Test 12: listen [::1] - Plus", conf: testConf12, }, { - plus: []string{ - "http://[::1]:8000/api/", + plus: []*model.APIDetails{ + { + URL: "http://[::1]:8000/api/", + Listen: "[::1]:8000", + Location: "/api/", + }, }, + name: "Test 13: listen [::]:8000 - Plus", conf: testConf13, }, { - oss: []string{ - "http://localhost:80/stub_status", - "http://127.0.0.1:80/stub_status", + oss: []*model.APIDetails{ + { + URL: "http://localhost:80/stub_status", + Listen: "localhost:80", + Location: "/stub_status", + }, + { + URL: "http://127.0.0.1:80/stub_status", + Listen: "127.0.0.1:80", + Location: "/stub_status", + }, }, + name: "Test 14: listen 127.0.0.1:80, server_name localhost - OSS", conf: testConf14, }, { - oss: []string{ - "http://localhost:80/stub_status", - "http://127.0.0.1:80/stub_status", + oss: []*model.APIDetails{ + { + URL: "http://localhost:80/stub_status", + Listen: "localhost:80", + Location: "/stub_status", + }, + { + URL: "http://127.0.0.1:80/stub_status", + Listen: "127.0.0.1:80", + Location: "/stub_status", + }, }, + name: "Test 15: listen :80, server_name localhost - OSS", conf: testConf15, }, { - oss: []string{ - "http://localhost:80/stub_status", - "http://127.0.0.1:80/stub_status", + oss: []*model.APIDetails{ + { + URL: "http://localhost:80/stub_status", + Listen: "localhost:80", + Location: "/stub_status", + }, + { + URL: "http://127.0.0.1:80/stub_status", + Listen: "127.0.0.1:80", + Location: "/stub_status", + }, }, + name: "Test 16: listen 80, server_name localhost - OSS", conf: testConf16, }, { - oss: []string{ - "http://localhost:80/stub_status", - "http://127.0.0.1:80/stub_status", + oss: []*model.APIDetails{ + { + URL: "http://localhost:80/stub_status", + Listen: "localhost:80", + Location: "/stub_status", + }, + { + URL: "http://127.0.0.1:80/stub_status", + Listen: "127.0.0.1:80", + Location: "/stub_status", + }, }, + name: "Test 17: location = /stub_status - OSS", conf: testConf17, }, { - oss: []string{ - "http://localhost:80/stub_status", - "http://127.0.0.1:80/stub_status", + oss: []*model.APIDetails{ + { + URL: "http://localhost:80/stub_status", + Listen: "localhost:80", + Location: "/stub_status", + }, + { + URL: "http://127.0.0.1:80/stub_status", + Listen: "127.0.0.1:80", + Location: "/stub_status", + }, }, - plus: []string{ - "http://localhost:80/api/", - "http://127.0.0.1:80/api/", + plus: []*model.APIDetails{ + { + URL: "http://localhost:80/api/", + Listen: "localhost:80", + Location: "/api/", + }, + { + URL: "http://127.0.0.1:80/api/", + Listen: "127.0.0.1:80", + Location: "/api/", + }, }, + name: "Test 18: listen 80 - OSS & Plus", conf: testConf18, }, { - plus: []string{ - "http://127.0.0.1:49151/api", - "http://127.0.0.1:49151/api", + plus: []*model.APIDetails{ + { + URL: "http://127.0.0.1:49151/api", + Listen: "127.0.0.1:49151", + Location: "/api", + }, + { + URL: "http://127.0.0.1:49151/api", + Listen: "127.0.0.1:49151", + Location: "/api", + }, }, + name: "Test 19: listen 127.0.0.1:49151 - Plus", conf: testConf19, }, + { + oss: []*model.APIDetails{ + { + URL: "http://config-status/stub_status", + Listen: "unix:/var/run/nginx/nginx-status.sock", + Location: "/stub_status", + }, + }, + name: "Test 20: unix:/var/run/nginx/nginx-status.sock - OSS Unix Socket", + conf: testConf20, + }, + { + plus: []*model.APIDetails{ + { + URL: "http://nginx-plus-api/api", + Listen: "unix:/var/run/nginx/nginx-plus-api.sock", + Location: "/api", + }, + }, + name: "Test 21: listen unix:/var/run/nginx/nginx-plus-api.sock- Plus Unix Socket", + conf: testConf21, + }, } { ctx := context.Background() f, err := os.CreateTemp(tmpDir, "conf") @@ -513,17 +694,18 @@ func TestNginxConfigParser_urlsForLocationDirective(t *testing.T) { payload, err := crossplane.Parse(f.Name(), parseOptions) require.NoError(t, err) - nginxConfigParser := NewNginxConfigParser(types.AgentConfig()) + ncp := NewNginxConfigParser(types.AgentConfig()) - var oss, plus []string + var oss, plus []*model.APIDetails assert.Len(t, payload.Config, 1) for _, xpConf := range payload.Config { assert.Len(t, xpConf.Parsed, 1) - err = nginxConfigParser.crossplaneConfigTraverse(ctx, &xpConf, + err = ncp.crossplaneConfigTraverse(ctx, &xpConf, func(ctx context.Context, parent, directive *crossplane.Directive) error { - _oss := nginxConfigParser.urlsForLocationDirective(parent, directive, stubStatusAPIDirective) - _plus := nginxConfigParser.urlsForLocationDirective(parent, directive, plusAPIDirective) + _oss := ncp.urlsForLocationDirectiveAPIDetails(parent, directive, + stubStatusAPIDirective) + _plus := ncp.urlsForLocationDirectiveAPIDetails(parent, directive, plusAPIDirective) oss = append(oss, _oss...) plus = append(plus, _plus...) @@ -539,7 +721,7 @@ func TestNginxConfigParser_urlsForLocationDirective(t *testing.T) { // linter doesn't like the duplicate handler and server function // nolint: dupl -func TestNginxConfigParser_pingPlusAPIEndpoint(t *testing.T) { +func TestNginxConfigParser_pingAPIEndpoint_PlusAPI(t *testing.T) { handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if req.URL.String() == "/good_api" { data := []byte("[1,2,3,4,5,6,7,8]") @@ -590,7 +772,10 @@ func TestNginxConfigParser_pingPlusAPIEndpoint(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { ctx := context.Background() - result := nginxConfigParser.pingPlusAPIEndpoint(ctx, fmt.Sprintf("%s%s", fakeServer.URL, test.endpoint)) + result := nginxConfigParser.pingAPIEndpoint(ctx, &model.APIDetails{ + URL: fmt.Sprintf("%s%s", fakeServer.URL, test.endpoint), + Listen: "", + }, "api") assert.Equal(t, test.expected, result) }) } @@ -598,7 +783,7 @@ func TestNginxConfigParser_pingPlusAPIEndpoint(t *testing.T) { // linter doesn't like the duplicate handler and server function // nolint: dupl -func TestNginxConfigParser_pingStubStatusAPIEndpoint(t *testing.T) { +func TestNginxConfigParser_pingAPIEndpoint_StubStatus(t *testing.T) { handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if req.URL.String() == "/good_api" { data := []byte(` @@ -657,8 +842,11 @@ Reading: 0 Writing: 1 Waiting: 1 for _, test := range tests { t.Run(test.name, func(t *testing.T) { ctx := context.Background() - statusAPI := fmt.Sprintf("%s%s", fakeServer.URL, test.endpoint) - result := nginxConfigParser.pingStubStatusAPIEndpoint(ctx, statusAPI) + statusAPI := &model.APIDetails{ + URL: fmt.Sprintf("%s%s", fakeServer.URL, test.endpoint), + Listen: "", + } + result := nginxConfigParser.pingAPIEndpoint(ctx, statusAPI, "stub_status") assert.Equal(t, test.expected, result) }) } diff --git a/internal/watcher/instance/nginx_process_parser.go b/internal/watcher/instance/nginx_process_parser.go index e88fac4e5b..7ad875af12 100644 --- a/internal/watcher/instance/nginx_process_parser.go +++ b/internal/watcher/instance/nginx_process_parser.go @@ -204,7 +204,10 @@ func convertInfoToInstance(nginxInfo Info) *mpi.Instance { ConfigPath: nginxInfo.ConfPath, Details: &mpi.InstanceRuntime_NginxRuntimeInfo{ NginxRuntimeInfo: &mpi.NGINXRuntimeInfo{ - StubStatus: "", + StubStatus: &mpi.APIDetails{ + Location: "", + Listen: "", + }, AccessLogs: []string{}, ErrorLogs: []string{}, LoadableModules: nginxInfo.LoadableModules, @@ -219,12 +222,18 @@ func convertInfoToInstance(nginxInfo Info) *mpi.Instance { ConfigPath: nginxInfo.ConfPath, Details: &mpi.InstanceRuntime_NginxPlusRuntimeInfo{ NginxPlusRuntimeInfo: &mpi.NGINXPlusRuntimeInfo{ - StubStatus: "", + StubStatus: &mpi.APIDetails{ + Location: "", + Listen: "", + }, AccessLogs: []string{}, ErrorLogs: []string{}, LoadableModules: nginxInfo.LoadableModules, DynamicModules: nginxInfo.DynamicModules, - PlusApi: "", + PlusApi: &mpi.APIDetails{ + Location: "", + Listen: "", + }, }, }, } diff --git a/internal/watcher/watcher_plugin.go b/internal/watcher/watcher_plugin.go index 5d1e14cd97..5c7a68cf7e 100644 --- a/internal/watcher/watcher_plugin.go +++ b/internal/watcher/watcher_plugin.go @@ -219,7 +219,8 @@ func (w *Watcher) monitorWatchers(ctx context.Context) { ) w.messagePipe.Process( newCtx, - &bus.Message{Topic: bus.NginxConfigUpdateTopic, Data: message.NginxConfigContext}, + &bus.Message{Topic: bus. + NginxConfigUpdateTopic, Data: message.NginxConfigContext}, ) } else { slog.DebugContext( diff --git a/test/config/collector/test-opentelemetry-collector-agent.yaml b/test/config/collector/test-opentelemetry-collector-agent.yaml index 8080573361..9b103b67f1 100644 --- a/test/config/collector/test-opentelemetry-collector-agent.yaml +++ b/test/config/collector/test-opentelemetry-collector-agent.yaml @@ -17,7 +17,10 @@ receivers: key_file: /tmp/key.pem ca_file: /tmp/ca.pem nginx/123: - endpoint: "http://localhost:80/status" + api_details: + url: "http://localhost:80/status" + listen: "" + location: "" collection_interval: 10s access_logs: - log_format: "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" \"$http_x_forwarded_for\"\"$upstream_cache_status\"" diff --git a/test/model/config.go b/test/model/config.go index 8d8cdc5594..e20759e7db 100644 --- a/test/model/config.go +++ b/test/model/config.go @@ -9,6 +9,11 @@ import "github.com/nginx/agent/v3/internal/model" func GetConfigContext() *model.NginxConfigContext { return &model.NginxConfigContext{ + StubStatus: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, AccessLogs: []*model.AccessLog{{Name: "access.logs"}}, ErrorLogs: []*model.ErrorLog{{Name: "error.log"}}, } @@ -22,6 +27,11 @@ func GetConfigContextWithNames( instanceID string, ) *model.NginxConfigContext { return &model.NginxConfigContext{ + StubStatus: &model.APIDetails{ + URL: "", + Listen: "", + Location: "", + }, AccessLogs: []*model.AccessLog{ { Name: accessLogName, diff --git a/test/protos/instances.go b/test/protos/instances.go index 6ea7c9b1eb..3bf88555f4 100644 --- a/test/protos/instances.go +++ b/test/protos/instances.go @@ -9,7 +9,7 @@ import ( "fmt" "os" - "github.com/nginx/agent/v3/api/grpc/mpi/v1" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/config" ) @@ -27,14 +27,14 @@ const ( childID4 = 321 ) -func GetAgentInstance(processID int32, agentConfig *config.Config) *v1.Instance { - return &v1.Instance{ - InstanceMeta: &v1.InstanceMeta{ +func GetAgentInstance(processID int32, agentConfig *config.Config) *mpi.Instance { + return &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ InstanceId: agentConfig.UUID, - InstanceType: v1.InstanceMeta_INSTANCE_TYPE_AGENT, + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_AGENT, Version: agentConfig.Version, }, - InstanceRuntime: &v1.InstanceRuntime{ + InstanceRuntime: &mpi.InstanceRuntime{ ProcessId: processID, BinaryPath: "/run/nginx-agent", ConfigPath: agentConfig.Path, @@ -42,20 +42,23 @@ func GetAgentInstance(processID int32, agentConfig *config.Config) *v1.Instance } } -func GetNginxOssInstance(expectedModules []string) *v1.Instance { - return &v1.Instance{ - InstanceMeta: &v1.InstanceMeta{ +func GetNginxOssInstance(expectedModules []string) *mpi.Instance { + return &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ InstanceId: ossInstanceID, - InstanceType: v1.InstanceMeta_INSTANCE_TYPE_NGINX, + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_NGINX, Version: "1.25.3", }, - InstanceRuntime: &v1.InstanceRuntime{ + InstanceRuntime: &mpi.InstanceRuntime{ ProcessId: processID, BinaryPath: "/usr/local/Cellar/nginx/1.25.3/bin/nginx", ConfigPath: "/usr/local/etc/nginx/nginx.conf", - Details: &v1.InstanceRuntime_NginxRuntimeInfo{ - NginxRuntimeInfo: &v1.NGINXRuntimeInfo{ - StubStatus: "", + Details: &mpi.InstanceRuntime_NginxRuntimeInfo{ + NginxRuntimeInfo: &mpi.NGINXRuntimeInfo{ + StubStatus: &mpi.APIDetails{ + Location: "", + Listen: "", + }, AccessLogs: []string{}, ErrorLogs: []string{}, LoadableModules: expectedModules, @@ -69,25 +72,28 @@ func GetNginxOssInstance(expectedModules []string) *v1.Instance { }, }, }, - InstanceChildren: []*v1.InstanceChild{{ProcessId: childID}, {ProcessId: childID2}}, + InstanceChildren: []*mpi.InstanceChild{{ProcessId: childID}, {ProcessId: childID2}}, }, } } -func GetNginxPlusInstance(expectedModules []string) *v1.Instance { - return &v1.Instance{ - InstanceMeta: &v1.InstanceMeta{ +func GetNginxPlusInstance(expectedModules []string) *mpi.Instance { + return &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ InstanceId: plusInstanceID, - InstanceType: v1.InstanceMeta_INSTANCE_TYPE_NGINX_PLUS, + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_NGINX_PLUS, Version: "1.25.3 (nginx-plus-r31-p1)", }, - InstanceRuntime: &v1.InstanceRuntime{ + InstanceRuntime: &mpi.InstanceRuntime{ ProcessId: processID, BinaryPath: "/usr/local/Cellar/nginx/1.25.3/bin/nginx", ConfigPath: "/etc/nginx/nginx.conf", - Details: &v1.InstanceRuntime_NginxPlusRuntimeInfo{ - NginxPlusRuntimeInfo: &v1.NGINXPlusRuntimeInfo{ - StubStatus: "", + Details: &mpi.InstanceRuntime_NginxPlusRuntimeInfo{ + NginxPlusRuntimeInfo: &mpi.NGINXPlusRuntimeInfo{ + StubStatus: &mpi.APIDetails{ + Location: "", + Listen: "", + }, AccessLogs: []string{}, ErrorLogs: []string{}, LoadableModules: expectedModules, @@ -102,19 +108,22 @@ func GetNginxPlusInstance(expectedModules []string) *v1.Instance { "stream_proxy_protocol_vendor_module", "stream_realip_module", "stream_ssl_module", "stream_ssl_preread_module", }, - PlusApi: "", + PlusApi: &mpi.APIDetails{ + Location: "", + Listen: "", + }, }, }, - InstanceChildren: []*v1.InstanceChild{{ProcessId: childID}, {ProcessId: childID2}}, + InstanceChildren: []*mpi.InstanceChild{{ProcessId: childID}, {ProcessId: childID2}}, }, } } -func GetUnsupportedInstance() *v1.Instance { - return &v1.Instance{ - InstanceMeta: &v1.InstanceMeta{ +func GetUnsupportedInstance() *mpi.Instance { + return &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ InstanceId: unsuportedInstanceID, - InstanceType: v1.InstanceMeta_INSTANCE_TYPE_UNIT, + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_UNIT, Version: "", }, InstanceConfig: nil, @@ -122,39 +131,39 @@ func GetUnsupportedInstance() *v1.Instance { } } -func GetMultipleInstances(expectedModules []string) []*v1.Instance { +func GetMultipleInstances(expectedModules []string) []*mpi.Instance { process1 := GetNginxOssInstance(expectedModules) process2 := getSecondNginxOssInstance(expectedModules) - return []*v1.Instance{process1, process2} + return []*mpi.Instance{process1, process2} } -func GetMultipleInstancesWithUnsupportedInstance() []*v1.Instance { +func GetMultipleInstancesWithUnsupportedInstance() []*mpi.Instance { process1 := GetNginxOssInstance([]string{}) process2 := GetUnsupportedInstance() - return []*v1.Instance{process1, process2} + return []*mpi.Instance{process1, process2} } -func GetInstancesNoParentProcess(expectedModules []string) []*v1.Instance { +func GetInstancesNoParentProcess(expectedModules []string) []*mpi.Instance { process1 := GetNginxOssInstance(expectedModules) process1.GetInstanceRuntime().ProcessId = 0 process2 := getSecondNginxOssInstance(expectedModules) process2.GetInstanceRuntime().ProcessId = 0 - return []*v1.Instance{process1, process2} + return []*mpi.Instance{process1, process2} } -func GetFileCache(files ...*os.File) (map[string]*v1.FileMeta, error) { - cache := make(map[string]*v1.FileMeta) +func GetFileCache(files ...*os.File) (map[string]*mpi.FileMeta, error) { + cache := make(map[string]*mpi.FileMeta) for _, file := range files { lastModified, err := CreateProtoTime("2024-01-09T13:22:21Z") if err != nil { return nil, err } - cache[file.Name()] = &v1.FileMeta{ + cache[file.Name()] = &mpi.FileMeta{ ModifiedTime: lastModified, Name: file.Name(), Hash: "BDEIFo9anKNvAwWm9O2LpfvNiNiGMx.c", @@ -164,34 +173,34 @@ func GetFileCache(files ...*os.File) (map[string]*v1.FileMeta, error) { return cache, nil } -func getSecondNginxOssInstance(expectedModules []string) *v1.Instance { +func getSecondNginxOssInstance(expectedModules []string) *mpi.Instance { process2 := GetNginxOssInstance(expectedModules) process2.GetInstanceRuntime().ProcessId = processID2 process2.GetInstanceMeta().InstanceId = secondOssInstanceID process2.GetInstanceRuntime().BinaryPath = "/opt/homebrew/etc/nginx/1.25.3/bin/nginx" - process2.GetInstanceRuntime().InstanceChildren = []*v1.InstanceChild{{ProcessId: childID3}, {ProcessId: childID4}} + process2.GetInstanceRuntime().InstanceChildren = []*mpi.InstanceChild{{ProcessId: childID3}, {ProcessId: childID4}} return process2 } -func GetHealthyInstanceHealth() *v1.InstanceHealth { - return &v1.InstanceHealth{ +func GetHealthyInstanceHealth() *mpi.InstanceHealth { + return &mpi.InstanceHealth{ InstanceId: GetNginxOssInstance([]string{}).GetInstanceMeta().GetInstanceId(), - InstanceHealthStatus: v1.InstanceHealth_INSTANCE_HEALTH_STATUS_HEALTHY, + InstanceHealthStatus: mpi.InstanceHealth_INSTANCE_HEALTH_STATUS_HEALTHY, } } -func GetUnhealthyInstanceHealth() *v1.InstanceHealth { - return &v1.InstanceHealth{ +func GetUnhealthyInstanceHealth() *mpi.InstanceHealth { + return &mpi.InstanceHealth{ InstanceId: GetNginxPlusInstance([]string{}).GetInstanceMeta().GetInstanceId(), - InstanceHealthStatus: v1.InstanceHealth_INSTANCE_HEALTH_STATUS_UNHEALTHY, + InstanceHealthStatus: mpi.InstanceHealth_INSTANCE_HEALTH_STATUS_UNHEALTHY, } } -func GetUnspecifiedInstanceHealth() *v1.InstanceHealth { - return &v1.InstanceHealth{ +func GetUnspecifiedInstanceHealth() *mpi.InstanceHealth { + return &mpi.InstanceHealth{ InstanceId: unsuportedInstanceID, - InstanceHealthStatus: v1.InstanceHealth_INSTANCE_HEALTH_STATUS_UNSPECIFIED, + InstanceHealthStatus: mpi.InstanceHealth_INSTANCE_HEALTH_STATUS_UNSPECIFIED, Description: fmt.Sprintf("failed to get health for instance %s, error: unable "+ "to determine health", unsuportedInstanceID), } From 426612af8405f416ebb49c2befd30af97b32df8d Mon Sep 17 00:00:00 2001 From: oliveromahony Date: Tue, 10 Dec 2024 15:15:55 +0000 Subject: [PATCH 6/7] Set the message identifiers as UUIDv7 (#943) * edited the message format for message id, fixed the install test --- .../collector/otel_collector_plugin_test.go | 13 +- internal/command/command_plugin.go | 5 +- internal/command/command_plugin_test.go | 7 +- internal/command/command_service.go | 10 +- internal/command/command_service_test.go | 7 +- internal/datasource/proto/message.go | 31 +++++ internal/datasource/proto/message_test.go | 128 ++++++++++++++++++ internal/file/file_manager_service.go | 9 +- internal/file/file_plugin.go | 6 +- internal/file/file_plugin_test.go | 4 +- internal/logger/logger.go | 4 +- internal/resource/resource_plugin.go | 4 +- .../watcher/file/file_watcher_service_test.go | 8 +- .../instance/nginx_config_parser_test.go | 7 +- internal/watcher/watcher_plugin_test.go | 6 +- pkg/uuid/uuid.go | 15 ++ test/helpers/os_utils.go | 15 ++ test/helpers/os_utils_test.go | 61 +++++++++ test/helpers/slog_utils.go | 48 +++++++ test/integration/install_uninstall_test.go | 8 +- .../grpc/mock_management_command_service.go | 7 +- .../mock/grpc/mock_management_file_service.go | 4 +- test/protos/data_plane_response.go | 10 +- 23 files changed, 353 insertions(+), 64 deletions(-) create mode 100644 internal/datasource/proto/message.go create mode 100644 internal/datasource/proto/message_test.go create mode 100644 test/helpers/os_utils_test.go create mode 100644 test/helpers/slog_utils.go diff --git a/internal/collector/otel_collector_plugin_test.go b/internal/collector/otel_collector_plugin_test.go index d686603f9b..cbe0c808a1 100644 --- a/internal/collector/otel_collector_plugin_test.go +++ b/internal/collector/otel_collector_plugin_test.go @@ -9,7 +9,6 @@ import ( "context" "errors" "fmt" - "strings" "testing" "github.com/nginx/agent/v3/test/protos" @@ -119,23 +118,13 @@ func TestCollector_Init(t *testing.T) { initError := collector.Init(context.Background(), nil) require.NoError(t, initError) - validateLog(t, tt.expectedLog, logBuf) + helpers.ValidateLog(t, tt.expectedLog, logBuf) require.NoError(t, collector.Close(context.TODO())) }) } } -func validateLog(t *testing.T, expectedLog string, logBuf *bytes.Buffer) { - t.Helper() - - if expectedLog != "" { - if !strings.Contains(logBuf.String(), expectedLog) { - t.Errorf("Expected log to contain %q, but got %q", expectedLog, logBuf.String()) - } - } -} - func TestCollector_InitAndClose(t *testing.T) { conf := types.OTelConfig(t) conf.Collector.Log.Path = "" diff --git a/internal/command/command_plugin.go b/internal/command/command_plugin.go index be66f8823d..c0ab746608 100644 --- a/internal/command/command_plugin.go +++ b/internal/command/command_plugin.go @@ -11,11 +11,10 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" - "github.com/google/uuid" - mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/bus" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" pkgConfig "github.com/nginx/agent/v3/pkg/config" @@ -249,7 +248,7 @@ func (cp *CommandPlugin) createDataPlaneResponse(correlationID string, status mp ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/command/command_plugin_test.go b/internal/command/command_plugin_test.go index 0481232f3f..5b46582fde 100644 --- a/internal/command/command_plugin_test.go +++ b/internal/command/command_plugin_test.go @@ -8,7 +8,6 @@ package command import ( "bytes" "context" - "strings" "testing" "time" @@ -18,6 +17,7 @@ import ( "github.com/nginx/agent/v3/internal/bus" "github.com/nginx/agent/v3/internal/command/commandfakes" "github.com/nginx/agent/v3/internal/grpc/grpcfakes" + "github.com/nginx/agent/v3/test/helpers" "github.com/nginx/agent/v3/test/protos" "github.com/nginx/agent/v3/test/stub" "github.com/nginx/agent/v3/test/types" @@ -211,10 +211,7 @@ func TestMonitorSubscribeChannel(t *testing.T) { time.Sleep(100 * time.Millisecond) - // Verify the logger was called - if s := logBuf.String(); !strings.Contains(s, "Received management plane request") { - t.Errorf("Unexpected log %s", s) - } + helpers.ValidateLog(t, "Received management plane request", logBuf) // Clear the log buffer logBuf.Reset() diff --git a/internal/command/command_service.go b/internal/command/command_service.go index 9d24c245d1..5c991e76d2 100644 --- a/internal/command/command_service.go +++ b/internal/command/command_service.go @@ -14,11 +14,13 @@ import ( "time" "github.com/cenkalti/backoff/v4" - "github.com/google/uuid" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" + "google.golang.org/protobuf/types/known/timestamppb" backoffHelpers "github.com/nginx/agent/v3/internal/backoff" @@ -86,7 +88,7 @@ func (cs *CommandService) UpdateDataPlaneStatus( request := &mpi.UpdateDataPlaneStatusRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -136,7 +138,7 @@ func (cs *CommandService) UpdateDataPlaneHealth(ctx context.Context, instanceHea request := &mpi.UpdateDataPlaneHealthRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -214,7 +216,7 @@ func (cs *CommandService) CreateConnection( request := &mpi.CreateConnectionRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/command/command_service_test.go b/internal/command/command_service_test.go index ad8c6f790c..9534414dbd 100644 --- a/internal/command/command_service_test.go +++ b/internal/command/command_service_test.go @@ -10,7 +10,6 @@ import ( "context" "errors" "log/slog" - "strings" "testing" "time" @@ -122,9 +121,9 @@ func TestCommandService_UpdateDataPlaneStatusSubscribeError(t *testing.T) { err := commandService.UpdateDataPlaneStatus(ctx, protos.GetHostResource()) require.Error(t, err) - if s := logBuf.String(); !strings.Contains(s, "Failed to send update data plane status") { - t.Errorf("Unexpected log %s", s) - } + helpers.ValidateLog(t, "Failed to send update data plane status", logBuf) + + logBuf.Reset() } func TestCommandService_CreateConnection(t *testing.T) { diff --git a/internal/datasource/proto/message.go b/internal/datasource/proto/message.go new file mode 100644 index 0000000000..a2d547ca01 --- /dev/null +++ b/internal/datasource/proto/message.go @@ -0,0 +1,31 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package proto + +import ( + "log/slog" + "time" + + "github.com/google/uuid" + agentUuid "github.com/nginx/agent/v3/pkg/uuid" +) + +// UUIDGenerator defines a function type for generating UUIDs. +type UUIDGenerator func() (uuid.UUID, error) + +// DefaultUUIDGenerator is the production implementation for generating UUIDv7. +var defaultUUIDGenerator UUIDGenerator = uuid.NewUUID + +// GenerateMessageID generates a unique message ID, falling back to sha256 and timestamp if UUID generation fails. +func GenerateMessageID() string { + uuidv7, err := defaultUUIDGenerator() + if err != nil { + slog.Debug("Issue generating uuidv7, using sha256 and timestamp instead", "error", err) + return agentUuid.Generate("%s", time.Now().String()) + } + + return uuidv7.String() +} diff --git a/internal/datasource/proto/message_test.go b/internal/datasource/proto/message_test.go new file mode 100644 index 0000000000..10418d44b4 --- /dev/null +++ b/internal/datasource/proto/message_test.go @@ -0,0 +1,128 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package proto + +import ( + "bytes" + "errors" + "regexp" + "testing" + + "github.com/nginx/agent/v3/test/helpers" + "github.com/nginx/agent/v3/test/stub" + "github.com/stretchr/testify/assert" + + "github.com/google/uuid" +) + +func TestUUIDv7Regex(t *testing.T) { + // Define the UUIDv7 regex + uuidv7Regex := regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`) + + // Define test cases + tests := []struct { + name string + input string + expectMatch bool + }{ + { + name: "Valid UUIDv7 with variant 8", + input: "01876395-3f9d-7c91-89a3-4f57e53a1a4b", + expectMatch: true, + }, + { + name: "Valid UUIDv7 with variant a", + input: "01876395-3f9d-7c91-9f00-4f57e53a1a4b", + expectMatch: true, + }, + { + name: "Invalid UUIDv7 - wrong version", + input: "01876395-3f9d-6c91-89a3-4f57e53a1a4b", + expectMatch: false, + }, + { + name: "Invalid UUIDv7 - wrong variant", + input: "01876395-3f9d-7c91-7a00-4f57e53a1a4b", + expectMatch: false, + }, + { + name: "Invalid UUIDv7 - extra characters", + input: "01876395-3f9d-7c91-89a3-4f57e53a1a4b123", + expectMatch: false, + }, + { + name: "Invalid UUIDv7 - missing characters", + input: "01876395-3f9d-7c91-89a3-4f57e53a", + expectMatch: false, + }, + } + + // Iterate over test cases + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + match := uuidv7Regex.MatchString(tt.input) + assert.Equal(t, tt.expectMatch, match, "Regex match result did not match expectation") + }) + } +} + +func TestGenerateMessageID(t *testing.T) { + tests := []struct { + name string + mockFunc func() (uuid.UUID, error) + expected string + expectError bool + }{ + { + name: "Valid UUID generation", + mockFunc: func() (uuid.UUID, error) { + return uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, nil + }, + expected: "01020304-0506-0708-090a-0b0c0d0e0f10", + expectError: false, + }, + { + name: "Fallback UUID generation due to error", + mockFunc: func() (uuid.UUID, error) { + return uuid.Nil, errors.New("mock error") + }, + expected: "", // Fallback UUIDs don't follow a fixed prefix but should not be empty + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defaultUUIDGenerator = tt.mockFunc + + if tt.expectError { + logBuf := &bytes.Buffer{} + stub.StubLoggerWith(logBuf) + + got := GenerateMessageID() + assert.NotEmpty(t, got) + + // Inspect logs + helpers.ValidateLog(t, "Issue generating uuidv7, using sha256 and timestamp instead", logBuf) + + logBuf.Reset() + } else { + got := GenerateMessageID() + + assert.Equal(t, tt.expected, got, "Expected UUID string to match") + } + + // reset + defaultUUIDGenerator = uuid.NewUUID + }) + } + defaultUUIDGenerator = func() (uuid.UUID, error) { + return uuid.UUID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, nil + } + + got := GenerateMessageID() + assert.Equal(t, "01020304-0506-0708-090a-0b0c0d0e0f10", got, "Expected correct UUID string") +} diff --git a/internal/file/file_manager_service.go b/internal/file/file_manager_service.go index 149d0ce64f..cc55f9876e 100644 --- a/internal/file/file_manager_service.go +++ b/internal/file/file_manager_service.go @@ -14,10 +14,11 @@ import ( "sync" "sync/atomic" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/model" "github.com/cenkalti/backoff/v4" - "github.com/google/uuid" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/config" "github.com/nginx/agent/v3/internal/grpc" @@ -96,7 +97,7 @@ func (fms *FileManagerService) UpdateOverview( request := &mpi.UpdateOverviewRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: requestCorrelationID.Value.String(), Timestamp: timestamppb.Now(), }, @@ -168,7 +169,7 @@ func (fms *FileManagerService) UpdateFile( Contents: contents, }, MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -325,7 +326,7 @@ func (fms *FileManagerService) fileUpdate(ctx context.Context, file *mpi.File) e getFile := func() (*mpi.GetFileResponse, error) { return fms.fileServiceClient.GetFile(ctx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: logger.GetCorrelationID(ctx), Timestamp: timestamppb.Now(), }, diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index aee199ff57..1b93565489 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -12,10 +12,10 @@ import ( "github.com/nginx/agent/v3/pkg/files" - "github.com/google/uuid" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/bus" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" "github.com/nginx/agent/v3/internal/model" @@ -319,7 +319,7 @@ func (fp *FilePlugin) handleConfigUploadRequest(ctx context.Context, msg *bus.Me response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -343,7 +343,7 @@ func (fp *FilePlugin) createDataPlaneResponse(correlationID string, status mpi.C ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/file/file_plugin_test.go b/internal/file/file_plugin_test.go index 2544fa4976..27c29949b1 100644 --- a/internal/file/file_plugin_test.go +++ b/internal/file/file_plugin_test.go @@ -13,8 +13,8 @@ import ( "time" "github.com/nginx/agent/v3/internal/bus/busfakes" + "github.com/nginx/agent/v3/internal/datasource/proto" - "github.com/google/uuid" "google.golang.org/protobuf/types/known/timestamppb" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" @@ -441,7 +441,7 @@ func TestFilePlugin_Process_ConfigApplyRollbackCompleteTopic(t *testing.T) { expectedResponse := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, diff --git a/internal/logger/logger.go b/internal/logger/logger.go index cc0728996b..ec7491f52a 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -13,8 +13,8 @@ import ( "path" "strings" - "github.com/google/uuid" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" ) const ( @@ -121,7 +121,7 @@ func (h contextHandler) observe(ctx context.Context) (as []slog.Attr) { } func GenerateCorrelationID() slog.Attr { - return slog.Any(CorrelationIDKey, uuid.NewString()) + return slog.Any(CorrelationIDKey, proto.GenerateMessageID()) } func GetCorrelationID(ctx context.Context) string { diff --git a/internal/resource/resource_plugin.go b/internal/resource/resource_plugin.go index c3dc5ca40e..a2c05ae654 100644 --- a/internal/resource/resource_plugin.go +++ b/internal/resource/resource_plugin.go @@ -9,8 +9,8 @@ import ( "context" "log/slog" - "github.com/google/uuid" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/model" "google.golang.org/protobuf/types/known/timestamppb" @@ -186,7 +186,7 @@ func (*Resource) createDataPlaneResponse(correlationID string, status mpi.Comman ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/watcher/file/file_watcher_service_test.go b/internal/watcher/file/file_watcher_service_test.go index 8595c8b4a5..fae18a2f2b 100644 --- a/internal/watcher/file/file_watcher_service_test.go +++ b/internal/watcher/file/file_watcher_service_test.go @@ -10,10 +10,10 @@ import ( "context" "os" "path" - "strings" "testing" "time" + "github.com/nginx/agent/v3/test/helpers" "github.com/nginx/agent/v3/test/stub" "github.com/fsnotify/fsnotify" @@ -127,9 +127,9 @@ func TestFileWatcherService_removeWatcher(t *testing.T) { fileWatcherService.directoriesBeingWatched.Store(testDirectory, true) fileWatcherService.removeWatcher(ctx, testDirectory) - if s := logBuf.String(); !strings.Contains(s, "Failed to remove file watcher") { - t.Errorf("Unexpected log %s", s) - } + helpers.ValidateLog(t, "Failed to remove file watcher", logBuf) + + logBuf.Reset() } func TestFileWatcherService_isEventSkippable(t *testing.T) { diff --git a/internal/watcher/instance/nginx_config_parser_test.go b/internal/watcher/instance/nginx_config_parser_test.go index 36f08c4a98..b37b4b3cc4 100644 --- a/internal/watcher/instance/nginx_config_parser_test.go +++ b/internal/watcher/instance/nginx_config_parser_test.go @@ -12,7 +12,6 @@ import ( "net/http" "net/http/httptest" "os" - "strings" "testing" "github.com/google/go-cmp/cmp" @@ -936,9 +935,9 @@ func TestNginxConfigParser_ignoreLog(t *testing.T) { ncp := NewNginxConfigParser(agentConfig) assert.Equal(t, test.expected, ncp.ignoreLog(test.logPath)) - if s := logBuf.String(); !strings.Contains(s, test.expectedLog) { - t.Errorf("Expected to receive log: %s", test.expectedLog) - } + helpers.ValidateLog(t, test.expectedLog, logBuf) + + logBuf.Reset() }) } } diff --git a/internal/watcher/watcher_plugin_test.go b/internal/watcher/watcher_plugin_test.go index c4b74d09a7..427b76af2b 100644 --- a/internal/watcher/watcher_plugin_test.go +++ b/internal/watcher/watcher_plugin_test.go @@ -11,8 +11,8 @@ import ( "time" "github.com/nginx/agent/v3/internal/bus/busfakes" + "github.com/nginx/agent/v3/internal/datasource/proto" - "github.com/google/uuid" "google.golang.org/protobuf/types/known/timestamppb" "github.com/nginx/agent/v3/internal/watcher/health" @@ -138,7 +138,7 @@ func TestWatcher_Process_ConfigApplySuccessfulTopic(t *testing.T) { response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, @@ -172,7 +172,7 @@ func TestWatcher_Process_RollbackCompleteTopic(t *testing.T) { response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, diff --git a/pkg/uuid/uuid.go b/pkg/uuid/uuid.go index ee18764493..b10d5bb885 100644 --- a/pkg/uuid/uuid.go +++ b/pkg/uuid/uuid.go @@ -12,6 +12,21 @@ import ( "github.com/google/uuid" ) +// Generate creates a UUID based on a hashed string derived from the input format and arguments. +// This function is used primarilty in generating the NGINX Id +// +// Parameters: +// - format: A format string, similar to fmt.Sprintf. +// - a: Variadic arguments to be substituted into the format string. +// +// Process: +// 1. Creates a SHA-256 hash from the formatted string (using `fmt.Sprintf`). +// 2. Converts the hash to a hexadecimal string. +// 3. Generates an MD5-based UUID using the hashed string. +// +// Returns: +// +// A string representation of the generated UUID. func Generate(format string, a ...interface{}) string { h := sha256.New() s := fmt.Sprintf(format, a...) diff --git a/test/helpers/os_utils.go b/test/helpers/os_utils.go index 5ff3dc9462..5670bb02c8 100644 --- a/test/helpers/os_utils.go +++ b/test/helpers/os_utils.go @@ -7,6 +7,8 @@ package helpers import ( "os" + "regexp" + "strings" "testing" "github.com/stretchr/testify/require" @@ -14,6 +16,7 @@ import ( const ( filePermission = 0o700 + specialChars = "#$%\x00\x01\n" ) func CreateDirWithErrorCheck(t testing.TB, dirName string) { @@ -40,3 +43,15 @@ func RemoveFileWithErrorCheck(t testing.TB, fileName string) { require.NoError(t, err) } + +// RemoveASCIIControlSignals removes all non-printable ASCII control characters from a string. +func RemoveASCIIControlSignals(t testing.TB, input string) string { + t.Helper() + + // Use a regex to match and remove ASCII control characters (0x00 to 0x1F and 0x7F). + // by matching all control characters (ASCII 0–31 and 127). + re := regexp.MustCompile(`[[:cntrl:]]`) + output := strings.Trim(re.ReplaceAllString(input, ""), specialChars) + + return output +} diff --git a/test/helpers/os_utils_test.go b/test/helpers/os_utils_test.go new file mode 100644 index 0000000000..b7d601580f --- /dev/null +++ b/test/helpers/os_utils_test.go @@ -0,0 +1,61 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package helpers + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// nolint: stylecheck +func TestRemoveASCIIControlSignals(t *testing.T) { + tests := []struct { + name string + input string + expected string + }{ + { + name: "No control characters", + input: "Hello, World!", + expected: "Hello, World!", + }, + { + name: "With control characters", + input: "Hello , World!", expected: "Hello, World!", + }, + { + name: "Only control characters", + input: " ", expected: "", + }, + { + name: "Mixed printable and control characters", + input: "Hello\nWorld\t!", + expected: "HelloWorld!", + }, + { + name: "Empty string", + input: "", + expected: "", + }, + { + name: "Agent version example", + input: " nginx-agent version v3.0.0-4a64a94", expected: "nginx-agent version v3.0.0-4a64a94", + }, + { + name: "Agent version example alpine", + input: "#nginx-agent version v3.0.0-f94d93a", + expected: "nginx-agent version v3.0.0-f94d93a", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := RemoveASCIIControlSignals(t, test.input) + assert.Equal(t, test.expected, result) + }) + } +} diff --git a/test/helpers/slog_utils.go b/test/helpers/slog_utils.go new file mode 100644 index 0000000000..650c72ee3b --- /dev/null +++ b/test/helpers/slog_utils.go @@ -0,0 +1,48 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package helpers + +import ( + "bytes" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +// ValidateLog checks if the expected log message is present in the provided log buffer. +// If the expected log message is not found, it reports an error to the testing framework. +// +// Parameters: +// - t (*testing.T): The testing object used to report errors. +// - expectedLog (string): The expected log message to validate against the log buffer. +// If empty, no validation is performed. +// - logBuf (*bytes.Buffer): The log buffer that contains the actual log messages. +// +// Behavior: +// - If the expected log message is not an empty string: +// - The function checks whether the log buffer contains the expected log message. +// - If the log message is missing, an error is reported using t.Errorf. +// +// Usage: +// - Use this function within test cases to validate that a specific log message was produced. +// +// Example: +// +// var logBuffer bytes.Buffer +// logBuffer.WriteString("App started successfully") +// ValidateLog(t, "App started successfully", &logBuffer) +func ValidateLog(t *testing.T, expectedLog string, logBuf *bytes.Buffer) { + t.Helper() + + if expectedLog != "" { + require.NotEmpty(t, logBuf) + + if !strings.Contains(logBuf.String(), expectedLog) { + t.Errorf("Expected log to contain %q, but got %q", expectedLog, logBuf.String()) + } + } +} diff --git a/test/integration/install_uninstall_test.go b/test/integration/install_uninstall_test.go index 62eeb50320..95f8444a31 100644 --- a/test/integration/install_uninstall_test.go +++ b/test/integration/install_uninstall_test.go @@ -159,10 +159,10 @@ func verifyAgentVersion(ctx context.Context, tb testing.TB, testContainer testco exitCode, cmdOut, err := testContainer.Exec(ctx, []string{"nginx-agent", "--version"}) require.NoError(tb, err) assert.Equal(tb, 0, exitCode) - stdoutStderr, _ := io.ReadAll(cmdOut) - versionOutput := strings.Trim(string(stdoutStderr), "#$%\x00\x01\n") - require.NoError(tb, err) + stdoutStderr, readAllErr := io.ReadAll(cmdOut) + versionOutput := helpers.RemoveASCIIControlSignals(tb, string(stdoutStderr)) + require.NoError(tb, readAllErr) assert.Equal(tb, expectedVersionOutput, versionOutput) } @@ -176,8 +176,10 @@ func installAgent(ctx context.Context, tb testing.TB, container testcontainers.C exitCode, cmdOut, err := container.Exec(ctx, installCmd) require.NoError(tb, err) + stdoutStderr, err := io.ReadAll(cmdOut) require.NoError(tb, err) + msg := fmt.Sprintf("expected error code of 0 from cmd %q. Got: %v\n %s", installCmd, exitCode, stdoutStderr) assert.Equal(tb, 0, exitCode, msg) diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 9d1192ea40..ce9abd24e7 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -20,8 +20,9 @@ import ( "sync" "github.com/gin-gonic/gin" - "github.com/google/uuid" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/pkg/files" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/timestamppb" @@ -362,8 +363,8 @@ func (cs *CommandService) addConfigApplyEndpoint() { request := mpi.ManagementPlaneRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), - CorrelationId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), + CorrelationId: proto.GenerateMessageID(), Timestamp: timestamppb.Now(), }, Request: &mpi.ManagementPlaneRequest_ConfigApplyRequest{ diff --git a/test/mock/grpc/mock_management_file_service.go b/test/mock/grpc/mock_management_file_service.go index 2e312182ff..4a5485a412 100644 --- a/test/mock/grpc/mock_management_file_service.go +++ b/test/mock/grpc/mock_management_file_service.go @@ -13,8 +13,8 @@ import ( "path/filepath" "strconv" - "github.com/google/uuid" "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" @@ -76,7 +76,7 @@ func (mgs *FileService) UpdateOverview( configUploadRequest := &v1.ManagementPlaneRequest{ MessageMeta: &v1.MessageMeta{ - MessageId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), CorrelationId: request.GetMessageMeta().GetCorrelationId(), Timestamp: timestamppb.Now(), }, diff --git a/test/protos/data_plane_response.go b/test/protos/data_plane_response.go index c7a01f5357..5ce05c5c01 100644 --- a/test/protos/data_plane_response.go +++ b/test/protos/data_plane_response.go @@ -6,21 +6,23 @@ package protos import ( - "github.com/google/uuid" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/protobuf/types/known/timestamppb" ) +const success = "Success" + func OKDataPlaneResponse() *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.NewString(), - CorrelationId: uuid.NewString(), + MessageId: proto.GenerateMessageID(), + CorrelationId: proto.GenerateMessageID(), Timestamp: timestamppb.Now(), }, CommandResponse: &mpi.CommandResponse{ Status: mpi.CommandResponse_COMMAND_STATUS_OK, - Message: "Success", + Message: success, }, InstanceId: ossInstanceID, } From 8d7c4debd1621bb60d46b20726eda50243d8facf Mon Sep 17 00:00:00 2001 From: oliveromahony Date: Thu, 12 Dec 2024 16:04:02 +0000 Subject: [PATCH 7/7] updated golang crypto (#946) --- go.mod | 8 ++++---- go.sum | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 8481ed0fe2..0a2dd1ce25 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e golang.org/x/mod v0.21.0 - golang.org/x/sync v0.9.0 + golang.org/x/sync v0.10.0 google.golang.org/protobuf v1.35.2 ) @@ -307,9 +307,9 @@ require ( github.com/vardius/message-bus v1.1.5 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.32.0 - golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/grpc v1.68.0 ) diff --git a/go.sum b/go.sum index 5a643b5455..adda7ce6c5 100644 --- a/go.sum +++ b/go.sum @@ -804,8 +804,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= @@ -842,8 +842,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -862,19 +862,19 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=