+
+Install NGINX App Protect on a host accessible by your NGINX Controller instance by following the appropriate steps for your operating system in the [Using NGINX App Protect with NGINX Controller]({{< relref "controller/admin-guides/install/install-for-controller.md" >}}) guide.
+
+{{< note >}}
+If you install NGINX App Protect by using any of the OS-specific install guides, **do not make changes to the `nginx.conf` file**.
+The NGINX Controller Agent manages `nginx.conf` settings and will make the appropriate adjustments for you.
+{{< /note >}}
+
+
+
+
+
+---
+
+## Add the NGINX App Protect Instance to NGINX Controller
+
+{{< include "controller/add-existing-instance.md" >}}
+
+
+
+---
+
+## What's Next
+
+You should now be ready to start your NGINX Controller with App Security trial. Refer to the following topics to get started:
+
+- [Configure the NGINX Controller Agent]({{< relref "/controller/admin-guides/config-agent/configure-the-agent.md" >}})
+- [Set Up Metrics Collection]({{< relref "/controller/admin-guides/config-agent/configure-metrics-collection.md" >}})
+- [Forward Metrics Data to an External Service]({{< relref "/controller/analytics/forwarders/_index.md" >}})
+- [Set up NGINX Controller Services]({{< relref "/controller/services/overview.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/admin-guides/install/try-nginx-controller.md b/content/controller/admin-guides/install/try-nginx-controller.md
new file mode 100644
index 000000000..03d15b816
--- /dev/null
+++ b/content/controller/admin-guides/install/try-nginx-controller.md
@@ -0,0 +1,281 @@
+---
+description: This quick-start tutorial shows you how to get started using F5 NGINX Controller
+ with NGINX Plus.
+docs: DOCS-260
+doctypes:
+- tutorial
+tags:
+- docs
+title: Trial NGINX Controller with NGINX Plus
+toc: true
+weight: 110
+---
+
+## Overview
+
+This quick-start tutorial shows you how to get started using F5 NGINX Controller with NGINX Plus.
+
+{{< caution >}}In this tutorial, NGINX Controller will install an embedded, self-hosted PostgreSQL database suitable for demo and trial purposes only. **These instructions are not meant for use in production environments**.{{< /caution >}}
+
+{{< see-also >}}If you want to try out NGINX Controller with the Application Security add-on, refer to [Trial NGINX Controller with App Security]({{< relref "/controller/admin-guides/install/try-nginx-controller-app-sec.md" >}}).{{< /see-also >}}
+
+
+
+---
+
+## Technical Requirements
+
+Make sure to review the [NGINX Controller Technical Specifications Guide]({{< relref "/controller/admin-guides/install/nginx-controller-tech-specs.md" >}}) for the requirements for your distribution and desired configuration.
+
+### Supported Distributions
+
+NGINX Controller, the NGINX Controller Agent, and the NGINX Controller Application Security Add-on support the following distributions and architectures.
+
+{{< see-also >}}Refer to the [NGINX Plus Technical Specifications](https://docs.nginx.com/nginx/technical-specs/) guide for the distributions that NGINX Plus supports.{{< /see-also >}}
+
+{{< bootstrap-table "table table-striped table-bordered" >}}
+
+|Distribution and Version|NGINX Controller (Control Plane)|Agent (Data Plane)|ADC App. Sec. (Data Plane)|APIM Adv. Sec. (Data Plane)|Notes|
+|--- |--- |--- |--- |--- |--- |
+|Amazon Linux 2 (x86_64)| Not supported|v3.0+ |Not supported|Not supported| |
+|Amazon Linux 2017.09+ (x86_64)| Not supported |v3.0+|Not supported |Not supported| |
+|CentOS 6.5+ (x86_64)| Not supported |v3.0+| Not supported |Not supported| • CentOS 6.5 and later versions in the CentOS 6 family are partially supported. • This distribution does not support AVRD.|
+|CentOS 7.4+ (x86_64)|v3.0+|v3.0+ | v3.12+ |v3.19+| • CentOS 7.4 and later versions in the CentOS 7 family are supported.|
+|Debian 8 (x86_64)| Not supported |v3.0–3.21|Not supported|Not supported|• This distribution does not support AVRD.|
+|Debian 9 (x86_64)|v3.0+|v3.0–3.21 | v3.12+ |v3.19+ | |
+|Debian 10 (x86_64)| Not supported |v3.17+ | v3.17+ |v3.19+| See the [NGINX Plus Admin Guide](https://docs.nginx.com/nginx/) for requirements for Debian 10. |
+|Red Hat Enterprise Linux 6.5+| Not supported |v3.0+| Not supported | Not supported| • RHEL 6.5 and later versions in the RHEL 6 family are partially supported.|
+|Red Hat Enterprise Linux 7.4+ (x86_64)|v3.5+|v3.5+ | v3.12+|v3.19+| • RHEL 7.4 and later versions in the RHEL 7 family are supported. • SELinux may interfere with NGINX Controller installation and operation. If you do enable SELinux, it must use permissive mode. Use of enforcing mode is not supported. |
+|Red Hat Enterprise Linux 8.0+ (x86_64)|v3.22+|v3.22+ | v3.22+| Not supported | • RHEL 8.0 and later versions in the RHEL 8 family are supported. • SELinux may interfere with NGINX Controller installation and operation. If you do enable SELinux, it must use permissive mode. Use of enforcing mode is not supported. |
+|Ubuntu 18.04 LTS (x86_64)|v3.0+|v3.0+ |v3.13+|v3.19+| |
+|Ubuntu 20.04 LTS (x86_64)|v3.20+|v3.12+|v3.16.1+|v3.19+| |
+
+{{< /bootstrap-table >}}
+
+
+
+#### Analytics, Visibility, and Reporting Daemon (AVRD)
+
+NGINX Controller v3.1 and later use an Analytics, Visibility, and Reporting daemon (AVRD) to aggregate and report app-centric metrics, which you can use to track and check the health of your apps. To learn more about these metrics, see the [NGINX Metrics Catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) topic.
+
+### Hardware Specs
+
+The following minimum hardware specifications are required for each node running NGINX Controller:
+
+- RAM: 8 GB RAM
+- CPU: 8-Core CPU @ 2.40 GHz or similar
+- Disk space: 155–255 GB free disk space. 255 GB of free space is recommended if NGINX Controller App Security is enabled. See the [Storage Requirements]({{< relref "/controller/admin-guides/install/nginx-controller-tech-specs.md#storage-requirements" >}}) section for a categorized list of the storage requirements.
+
+### Supported NGINX Plus Versions
+
+NGINX Controller supports the following [NGINX Plus](https://www.f5.com/products/nginx/nginx-plus) versions:
+
+{{< bootstrap-table "table table-striped table-bordered" >}}
+
+| NGINX Plus | NGINX Controller | NGINX Controller ADC | NGINX Controller APIM |
+|------------|------------------|----------------------|-----------------------|
+| R30 | Not supported | 3.22.9+ | Not supported |
+| R29 | Not supported | 3.22.9+ | 3.19.6+ |
+| R28 | Not supported | 3.22.6+ | 3.19.6+ |
+| R27 | Not supported | 3.22.4+ | 3.19.6+ |
+| R26 | Not supported | 3.22.2+ | 3.19.6+ |
+| R25 | Not supported | 3.20.1+ | 3.19.2+ |
+| R24 | 3.17+ | 3.20+ | 3.18+ |
+| R23 | 3.12+ | 3.20.0 - 3.22.2 | 3.18+ |
+| R22 | 3.5+ | 3.20.0 - 3.22.1 | 3.18+ |
+| R21 | 3.5 - 3.12 | Not supported | Not supported |
+| R20 | 3.0 - 3.12 | Not supported | Not supported |
+| R19 | 2.6 - 3.5 | Not supported | Not supported |
+
+{{< /bootstrap-table >}}
+
+---
+
+## Sign Up for a Trial License
+
+First, you need to sign up for a trial license for NGINX Controller. The trial includes access to NGINX Plus, the NGINX Controller Application Delivery module, and the Application Security add-on.
+
+1. Go to [MyF5](https://account.f5.com/myf5) and create a new account.
+1. Verify your account and log in to MyF5.
+1. On the MyF5 landing page, activate the NGINX Controller free trial.
+1. On the MyF5 **Trials** page, select Launch Your Trial.
+1. Download the NGINX Controller package.
+1. Make note of your Association Token. You will use this to [license your NGINX Controller instance]({{< relref "/controller/platform/licensing-controller.md#add-a-license-to-nginx-controller" >}}).
+
+
+
+---
+
+## Install NGINX Controller Prerequisites
+
+{{< include "controller/helper-script-prereqs.md" >}}
+
+
+
+---
+
+## Install NGINX Controller
+
+Install NGINX Controller on a dedicated node that **does not** already have Kubernetes configured. NGINX Controller does not support pre-configured Kubernetes implementations at this time. The installer for NGINX Controller will install and configure Kubernetes for you.
+
+{{< important >}}Before installing NGINX Controller, you must **disable swap on the host**; this is required by Kubernetes in order for the kubelet to work properly. Refer to your Linux distribution documentation for specific instructions for disabling swap for your system. For more information about this requirement, see the AskF5 knowledge base article [K82655201](https://support.f5.com/csp/article/K82655201) and the [kubeadm installation guide](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#before-you-begin) in the Kubernetes documentation.{{< /important >}}
+
+{{< caution >}}**For RHEL 8 deployments**, complete the additional prerequisite steps in the [Installing NGINX on RHEL 8]({{< relref "/controller/admin-guides/install/install-nginx-controller-rhel-8.md" >}}) guide before installing NGINX Controller. RHEL 8 support is a **beta** feature.{{< /caution >}}
+
+To install NGINX Controller, take the following steps:
+
+1. Download the NGINX Controller installer package from the [MyF5 Customer Portal](https://my.f5.com/manage/s/downloads).
+1. Extract the installer package files:
+
+ ```bash
+ tar xzf controller-installer-.tar.gz
+ ```
+
+1. Run the installation script:
+
+ ```bash
+ cd controller-installer
+ ./install.sh
+ ```
+
+1. When prompted to use an embedded config DB, type `y`.
+
+1. The installation script walks through a series of steps and asks for the following inputs:
+
+ - **Config database volume type**: Specify the type of volume to use to store the config database: local, NFS, or AWS. We recommend choosing `local` for demo and trial purposes.
+
+ {{< see-also >}}Refer to the [NGINX Controller Technical Specifications Guide]({{< relref "/controller/admin-guides/install/nginx-controller-tech-specs.md#local-or-external-storage" >}}) for more information about the volume options and requirements.{{< /see-also >}}
+
+ - **Analytics database volume type**: Specify the type of volume to use to store the analytics database: local, NFS, or AWS. We recommend choosing `local` for demo and trial purposes.
+ - **EULA**: Read the end-user license agreement. Type either `y` to accept or `n` to exit.
+ - **SMTP**
+ - **SMTP Host**: Provide the host name or IP address of an SMTP server. This is used to send password recovery emails. For trial purposes, if you don't need to receive these communications, you can enter a value of "example.com" or something similar.
+ - **SMTP Port**: The port of the SMTP server.
+ - **SMTP Authentication**: Select `y` or `n` to authenticate when connecting to the SMTP server.
+ - **Use TLS for SMTP Communication**: Select `y` or `n` to use SSL for SMTP server connections.
+ - **Do not reply email address**: The sender's email address. For example, `donotreply@example.com`.
+ - **Admin**
+ - **First name**: The first name for the initial admin user.
+ - **Last name**: The last name for the initial admin user.
+ - **Email address**: The contact email address for the initial admin user.
+ - **Password**: The initial admin's password. Passwords must be 6-64 characters long and must include letters and digits.
+ - **FQDN**: Fully qualified domain name (FQDN) -- a resolvable domain name for the NGINX Controller server. You can use the FQDN to access the NGINX Controller web interface.
+ Additionally, the FQDN is used by Controller Agents when connecting to NGINX Controller.
+ - **SSL/TLS certificates**: Type `y` to generate and use self-signed certs for running NGINX Controller over HTTPS, or type `n` to provide your own certs.
+
+ {{< important >}}
+If you provide your own SSL/TLS certificates, you'll need a complete certificate chain file, with the intermediate CA cert appended to the server cert; the server certificate must appear **before** the chained certificates in the combined file.
+ {{< /important >}}
+
+1. Log in to NGINX Controller at `https:///login`. Use the admin email address and password that you provided during the installation process.
+
+1. Once NGINX Controller is installed, you may safely delete the installer package that you downloaded and extracted.
+
+
+
+---
+
+## License NGINX Controller
+
+To add a license to NGINX Controller, take the following steps:
+
+1. Go to `https:///platform/license` and log in.
+1. In the **Upload a license** section, select an upload option:
+
+ - **Upload license file** -- Locate and select your license file in the file explorer.
+ - **Paste your Association Token or license file** -- Paste your customer Association Token or the contents of your NGINX Controller license file. These are available on the [MyF5 Customer Portal](https://account.f5.com/myf5).
+
+1. Select **Save license**.
+
+{{< see-also >}}
+To add a license using the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}}), send a PUT request to the `/platform/license` endpoint. Provide your CAT or NGINX Controller license as a base64-encoded string in the JSON request body.
+{{< /see-also >}}
+
+
+
+
+---
+
+## Install NGINX Plus
+
+### Prerequisites
+
+- Make sure to review the [NGINX Plus Technical Specifications Guide](https://docs.nginx.com/nginx/technical-specs/) for the requirements for your distribution and desired configuration.
+- You'll need the NGINX Plus certificate and public key files (`nginx-repo.crt` and `nginx-repo.key`) that were provided when you signed up for the trial license. If you don't have these files, you can use the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}}) to download them.
+
+#### How to Download the NGINX Plus Cert and Key using the NGINX Controller API
+
+The NGINX Controller API uses session cookies to authenticate requests. The session cookie is returned in response to a `GET /api/v1/platform/login` request. See the Login endpoint in the [NGINX Controller API Reference]({{< relref "/controller/api/_index.md" >}}) documentation for information about session cookie timeouts and invalidation.
+
+{{< tip >}}
+You can send a GET request to the login endpoint to find the status of the session token.
+{{< /tip >}}
+
+For example:
+
+- Login and capture the session cookie:
+
+ ```curl
+ curl -c cookie.txt -X POST --url 'https://198.51.100.10/api/v1/platform/login' --header 'Content-Type: application/json' --data '{"credentials": {"type": "BASIC","username": "arthur@arthurdent.net","password": "Towel$123"}}'
+ ```
+
+- Use the session cookie to authenticate and get the session status:
+
+ ```curl
+ curl -b cookie.txt -c cookie.txt -X GET --url 'https://198.51.100.10/api/v1/platform/login'
+ ```
+
+
+
+
+To use the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}}) to download your NGINX Plus certificate and key bundle as a gzip or JSON file, send a GET request to the `/platform/licenses/nginx-plus-licenses/controller-provided` endpoint.
+
+For example:
+
+- Download JSON file:
+
+ ```bash
+ curl -b cookie.txt -c cookie.txt --header 'Content-Type: application/json' -X GET --url 'https://192.0.2.0/api/v1/platform/licenses/nginx-plus-licenses/controller-provided' --output nginx-plus-certs.json
+ ```
+
+- Download GZIP file:
+
+ ```bash
+ curl -b cookie.txt -c cookie.txt -X GET --url 'https://192.0.2.0/api/v1/platform/licenses/nginx-plus-licenses/controller-provided' --output nginx-plus-certs.gz
+ ```
+
+{{< note >}}
+If you are using a self-signed certificate you will need to add `-k` (allow insecure connections) to your curl command to be able to download your NGINX Plus certificate and key bundle.
+{{< /note >}}
+
+
+Once you have downloaded your certificate and key bundle you will need to expand the `.gz` file to get your certificate and key pair.
+
+For example:
+
+```bash
+gunzip nginx-plus-certs.gz
+```
+
+### Steps
+
+Take the following steps to install NGINX Plus:
+
+{{< important >}}
+You need the NGINX Plus certificate and public key files (`nginx-repo.crt` and `nginx-repo.key`) that were provided when you signed up for the trial license.
+{{< /important >}}
+
+1. First, make sure to review the [NGINX Plus Technical Specifications Guide](https://docs.nginx.com/nginx/technical-specs/) for the requirements for your distribution and desired configuration.
+2. To install NGINX Plus, follow the instructions in the [NGINX Plus Installation Guide](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/). Refer to the relevant section for your distribution.
+
+
+
+---
+
+## Add an NGINX Plus Instance to NGINX Controller
+
+{{< include "controller/add-existing-instance.md" >}}
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/admin-guides/install/using-helper-script.md b/content/controller/admin-guides/install/using-helper-script.md
new file mode 100644
index 000000000..49828b201
--- /dev/null
+++ b/content/controller/admin-guides/install/using-helper-script.md
@@ -0,0 +1,450 @@
+---
+description: Learn how to update F5 NGINX Controller installation settings and manage
+ the NGINX Controller service using the helper.sh script.
+docs: DOCS-261
+doctypes:
+- task
+tags:
+- docs
+title: Update NGINX Controller Settings with helper.sh
+toc: true
+weight: 200
+---
+
+## Overview
+
+You can use the F5 NGINX Controller `helper.sh` script to update NGINX Controller installation settings and manage the NGINX Controller process. This tutorial shows you how to use `helper.sh` to perform the following tasks:
+
+- Install the NGINX Controller prerequisites
+- View the version of NGINX Controller that's installed and running
+- Start, stop, and restart NGINX Controller
+- Back up and restore the NGINX Controller config and encryption keys
+- Restore the embedded config database
+- Get the NGINX Plus repository key and certificate files (deprecated for `helper.sh` in NGINX Controller v3.9)
+- Update the SMTP settings
+- Update the database settings
+- Update or replace the TLS certificates
+- Print the NGINX Controller logs
+- Create a support package
+
+## Install NGINX Controller Prerequisites
+
+
+
+{{< include "controller/helper-script-prereqs.md" >}}
+
+
+
+
+
+---
+
+## View the Installed NGINX Version
+
+To see which version of NGINX Controller is installed and running, type the following command:
+
+``` bash
+/opt/nginx-controller/helper.sh version
+```
+
+The output looks similar to the following:
+
+``` bash
+Installed version: 3.14.0
+Running version: 3.14.0
+```
+
+
+
+---
+
+## Start, Stop, and Restart NGINX Controller
+
+
+You can use the `helper.sh` script to start, stop, restart, and check the status of the NGINX Controller process.
+
+``` bash
+/opt/nginx-controller/helper.sh controller start
+/opt/nginx-controller/helper.sh controller stop
+/opt/nginx-controller/helper.sh controller restart
+/opt/nginx-controller/helper.sh controller status
+```
+
+
+
+---
+
+## Back Up and Restore Config and Encryption Keys
+
+
+
+After installing NGINX Controller, you should back up the cluster config and encryption keys. You'll need these if you ever need to restore the NGINX config database on top of a new NGINX Controller installation.
+
+- To back up the NGINX Controller cluster configuration and encryption keys:
+
+ ```bash
+ /opt/nginx-controller/helper.sh cluster-config save
+ ```
+
+ The file is saved to `/opt/nginx-controller/cluster-config.tgz`.
+
+- To restore the cluster's config and encryption keys, take the following steps:
+
+ ```bash
+ /opt/nginx-controller/helper.sh cluster-config load
+ ```
+
+
+
+
+
+---
+
+## Restore Embedded Config Database
+
+
+
+This section explains how to restore the embedded config database from the latest backup file or a specific, timestamped file.
+
+{{< important >}}If you restore the config database on top of a new installation of NGINX Controller, make sure to follow the steps to [restore your NGINX config and encryption keys]({{< relref "/controller/admin-guides/backup-restore/backup-restore-cluster-config.md" >}}) afterward. {{< /important >}}
+
+- To restore the embedded NGINX Controller config database **from the latest automated backup**, run the following command:
+
+ ```bash
+ /opt/nginx-controller/helper.sh backup restore
+ ```
+
+- To restore the embedded config database from **a specific backup file**:
+
+ ```bash
+ /opt/nginx-controller/helper.sh backup restore
+ ```
+
+ - If you installed the embedded config database on a **local volume**, the backup files are located in `/opt/nginx-controller/postgres_data/`.
+
+ - If you installed the embedded config database on an **NFS volume**, follow the steps in [(NFS) Copy Config Database Backup to Local Volume for Restoration]({{< relref "/controller/admin-guides/backup-restore/backup-restore-embedded-config-db.md#nfs-copy-config-database-backup-to-local-volume-for-restoration" >}}) to download the backup file to your local volume, and then use the `helper.sh` script to restore from it.
+
+
+
+
+
+---
+
+## Get NGINX Plus Repository Key and Certificate
+
+To install NGINX Plus as a data plane for NGINX Controller, you need to have the NGINX repository key and certificate files.
+
+{{< deprecated >}}Using the helper.sh script to download your NGINX Plus certificate and key bundle is deprecated in in NGINX Controller v3.9.{{< /deprecated >}}
+
+{{< see-also >}}If you're running NGINX Controller v3.10+, you can use the REST API to [Download the NGINX Plus Cert and Key Bundle]({{< relref "/controller/admin-guides/install/get-n-plus-cert-and-key.md" >}}). {{< /see-also >}}
+
+If you're running NGINX Controller 3.9 or earlier, use the `helper.sh` script to extract the NGINX repository key and certificate files:
+
+```bash
+/opt/nginx-controller/helper.sh repository-cred [-c|--cert ] [-k|--key ]
+```
+
+{{< important >}}
+
+Make sure that you've [uploaded your license in NGINX Controller]({{< relref "licensing-controller.md" >}}) first before running the `helper.sh repository-cred` command to extract the repository files.
+
+{{< /important >}}
+
+
+
+| Options | Description |
+|----------|-------------|
+| `-c` \| `--cert` | Creates a certificate called ``. The default file name is `nginx-repo.crt` in the current directory.|
+| `-k` \| `--key` | Creates a key called ``. The default file name is `nginx-repo.key` in the current directory. |
+
+
+
+---
+
+## Update SMTP Settings
+
+Use the `helper.sh` script to change the SMTP address; port; TLS; sender; and optionally, the username and password.
+
+``` bash
+/opt/nginx-controller/helper.sh configsmtp [auth] [username] [password]
+```
+
+For example:
+
+``` bash
+/opt/nginx-controller/helper.sh configsmtp 192.0.2.0 25 false noreply@example.com true user1 password1
+```
+
+
+
+| Options | Description |
+|----------|-------------|
+| `address` | The host name or IP address of the SMTP server. |
+| `port` | The port of the SMTP server. |
+| `tls` | `true` or `false`. Set to `true` to require SSL for connections to the SMTP server. |
+| `from` | Sender's email address. |
+| `auth` | `true` or `false`. Set to `true` to authenticate when connecting to the SMTP server. |
+| `username` | The username to use for access to the SMTP server. |
+| `password` | The password to use for access to the SMTP server. |
+
+
+
+### Environment Variables
+
+We strongly recommend that you use environment variables, especially for passwords, to prevent exposing sensitive information in system processes (for example, `ps`, `top`) and the bash history.
+
+You use these SMTP environment variables with NGINX Controller:
+
+| Environment Variables | Description |
+|----------|-------------|
+| `CTR_SMTP_HOST` | The host name or IP address of the SMTP server. |
+| `CTR_SMTP_PORT` | The port of the SMTP server.|
+| `CTR_SMTP_TLS` | `true` or `false`; Set to `true` to require SSL for connections to the SMTP server. |
+| `CTR_SMTP_FROM` | Sender's email address. |
+| `CTR_SMTP_AUTH` | `true` or `false`; Set to `true` to authenticate when connecting to the SMTP server. |
+| `CTR_SMTP_USER` | The username to use for access to the SMTP server. |
+| `CTR_SMTP_PASS` | The password to use for access to the SMTP server. |
+
+For example:
+
+``` bash
+CTR_SMTP_HOST=192.0.2.0 \
+CTR_SMTP_PORT=25 \
+CTR_SMTP_TLS=false \
+CTR_SMTP_FROM=noreply@nginx.test \
+CTR_SMTP_AUTH=true CTR_SMTP_USER=user1 CTR_SMTP_PASS=password1 \
+/opt/nginx-controller/helper.sh configsmtp
+```
+
+
+
+---
+
+## Update Database Settings
+
+Use the `helper.sh` script to change the external config database address; port; and optionally, the username, password, and certificate authentication. However, if your current installation uses an internal config database, then these settings are read-only and cannot be modified using the `helper.sh` script (password and certificates will be automatically rotated with each Controller update).
+
+``` bash
+/opt/nginx-controller/helper.sh configdb [username] [password] [ssl] [ca] [cert] [key]
+```
+
+For example:
+
+``` bash
+/opt/nginx-controller/helper.sh configdb 192.0.2.1 5432 user1 password1 false
+```
+
+
+
+| Options | Description |
+|----------|-------------|
+| `address` | The host name or IP address of config database. |
+| `port` | The port of the database. |
+| `username` | The username to use for access to the config database. |
+| `password` | The password to use for access to the config database. |
+| `ssl` | `true` or `false`. Set to 'true' to require SSL for connections to the config database. |
+| `ca` | CA certificate file path. |
+| `cert` | Certificate file path. |
+| `key` | Key file path. |
+
+
+
+### Environment Variables
+
+We strongly recommend that you use environment variables, especially for passwords, to prevent exposing sensitive information in system processes (for example, `ps`, `top`) and the bash history.
+
+You can use these database environment variables with NGINX Controller:
+
+| Environment Variables | Description |
+|----------|-------------|
+| `CTR_DB_HOST` | The host name or IP address of the config database. |
+| `CTR_DB_PORT` | The port of the config database used for incoming connections. |
+| `CTR_DB_USER` | The username for the account to use for access to the config database; must be provided with password. |
+| `CTR_DB_PASS` | The password for the account to use for access to the config database; must be provided with username. |
+| `CTR_DB_ENABLE_SSL` | `true` or `false`; Set to `true` to require SSL for connections to the config database. |
+| `CTR_DB_CA` | CA certificate file path. |
+| `CTR_DB_CLIENT_CERT` | Certificate file path. |
+| `CTR_DB_CLIENT_KEY` | Key file path. |
+
+For example:
+
+```bash
+CTR_DB_HOST=192.0.2.1 \
+CTR_DB_PORT=5432 \
+CTR_DB_USER=user1 \
+CTR_DB_PASS=password1 \
+CTR_DB_ENABLE_SSL=false \
+/opt/nginx-controller/helper.sh configdb
+```
+
+
+
+---
+
+## Update or Replace TLS Certificates
+
+Use the `helper.sh` script to update or replace the TLS certificates that are used to connect to NGINX Controller.
+
+``` bash
+/opt/nginx-controller/helper.sh configtls
+```
+
+
+
+| Options | Description |
+|----------|-------------|
+| `cert_file` | Certificate file path. |
+| `key_file` | Key file path. |
+
+
+
+---
+
+## Print NGINX Controller Logs
+
+To print the NGINX Controller logs, enter the following command:
+
+``` bash
+/opt/nginx-controller/helper.sh logs
+```
+
+
+
+---
+
+## Add a Custom Logo
+
+The NGINX Controller logo in the user interface is replaceable with a custom logo. The requirements being:
+
+- The logo file is in SVG format.
+- The logo is square in shape.
+
+{{< note >}} The above steps modify the logo in the top left corner and in the menu, not the favicon. {{< /note >}}
+
+Follow the steps below to replace the logo:
+
+1. Connect to the NGINX Controller host using 'ssh'.
+1. Transfer the logo file to NGINX Controller using one of the following methods:
+ 1. Method 1: Download the file using curl after connecting to the host using the command `curl https://example.com/custom-logo.svg`.
+ 1. Method 2: Upload the logo to the host using SCP: `scp /local/path/custom-logo.svg user@controller-host:/remote/path`.
+ 1. Method 3: Copy/Paste the logo file.
+ 1. Copy the logo file to the clipboard before connecting to the host.
+ 1. After connecting to the host, paste the file.
+1. Run `helper.sh setlogo ` ( is the name of the SVG file).
+1. Wait for approximately five minutes for the cache to clear and the logo to appear in the user interface.
+1. Re-run the `setlogo` command on each NGINX Controller node. This has to be done after an upgrade or reinstallation.
+
+
+
+---
+
+## Create a Support Package
+
+You can create a support package for NGINX Controller that you can use to diagnose issues.
+
+{{< note >}}
+You will need to provide a support package if you open a ticket with NGINX Support via the [MyF5 Customer Portal](https://account.f5.com/myf5).
+{{< /note >}}
+
+```bash
+/opt/nginx-controller/helper.sh supportpkg [-o|--output ] [-s|--skip-db-dump] [-t|--timeseries-dump ]
+```
+
+
+
+| Options | Description |
+|----------|-------------|
+| `-o` \| `--output` | Save the support package file to ``. |
+| `-s` \| `--skip-db-dump` | Don't include the database dump in the support package. |
+| `-t` \| `--timeseries-dump ` | Include the last `` of timeseries data in the support package (default 12 hours). |
+
+Take the following steps to create a support package:
+
+1. Open a secure shell (SSH) connection to the NGINX Controller host and log in as an administrator.
+
+1. Run the `helper.sh` utility with the `supportpkg` option:
+
+ ```bash
+ /opt/nginx-controller/helper.sh supportpkg
+ ```
+
+ The support package is saved to:
+
+ `/var/tmp/supportpkg-.tar.gz`
+
+ For example:
+
+ `/var/tmp/supportpkg-20200127T063000PST.tar.gz`
+
+1. Run the following command on the machine where you want to download the support package to:
+
+ ``` bash
+ scp @:/var/tmp/supportpkg-.tar.gz /local/path
+ ```
+
+### Support Package Details
+
+{{< include "controller/helper-script-support-package-details.md" >}}
+
+
+
+
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/_index.md b/content/controller/analytics/_index.md
new file mode 100644
index 000000000..7a62df501
--- /dev/null
+++ b/content/controller/analytics/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn about the F5 NGINX Controller Analytics module.
+menu:
+ docs:
+ parent: NGINX Controller
+ title: Analytics
+title: Analytics
+weight: 120
+url: /nginx-controller/analytics/
+---
diff --git a/content/controller/analytics/alerts/_index.md b/content/controller/analytics/alerts/_index.md
new file mode 100644
index 000000000..4bae6e7ab
--- /dev/null
+++ b/content/controller/analytics/alerts/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn about F5 NGINX Controller alerts and notifications.
+menu:
+ docs:
+ parent: Analytics
+ weight: 10
+title: Alerts
+weight: 100
+url: /nginx-controller/analytics/alerts/
+---
diff --git a/content/controller/analytics/alerts/about-alerts.md b/content/controller/analytics/alerts/about-alerts.md
new file mode 100644
index 000000000..9277494ed
--- /dev/null
+++ b/content/controller/analytics/alerts/about-alerts.md
@@ -0,0 +1,226 @@
+---
+description: Learn about NGINX Controller Alerts and Notifications.
+docs: DOCS-520
+doctypes:
+- concept
+tags:
+- docs
+title: About Alerts
+toc: true
+weight: 100
+---
+
+## Overview
+
+The F5 NGINX Controller Analytics module lets you configure alerts and notifications, so you can stay informed about your system and app performance. In this topic, you'll learn about [alerts](#alerts), [alert rules](#alert-rules), and [alert notifications](#alert-notifications).
+
+{{< see-also >}}
+Refer to [Manage Alerts]({{< relref "/controller/analytics/alerts/manage-alerts.md" >}}) to learn how to set up alerts.
+{{< /see-also >}}
+
+## Alerts
+
+An *alert* is generated when the criteria for an alert rule are met.
+All alerts contain the following information:
+
+
+
+| Name | Description |
+|---|---|
+| `started_timestamp` | The time at which the alert was triggered.|
+| `last_checked_timestamp` | The time at which the last alert check occurred.|
+| `started_value` | The value of the alert metric at the time the alert was triggered.|
+| `last_checked_value` | The value of the alert metric when it was last checked.|
+| `dimensions` | The list of dimension values for which the alert was triggered.|
+
+## Alert Rules
+
+An *Alert Rule* defines the conditions that will trigger an alert. NGINX Controller generates names for alert rules automatically. An alert rule consists of the following information:
+
+
+
+| Name | Description |
+|---|---|
+| `name` | A unique identifier for the alert rule.|
+| `display name` | A human-friendly name that helps you identify what the alert rule does. |
+| `metric` | The [metric]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) that you want to monitor. {{< note >}}An alert rule can monitor one metric.{{< /note >}}|
+| `operator` | The operator that will be applied to the value of the metric to check if an alert should be triggered. There are two available operators: `le` - less or equal and `ge` - greater or equal.|
+| `threshold` | Defines the value that, when exceeded, will trigger an alert. {{< tip >}}You can find the allowed threshold value(s) for each metric in the **unit** field of the metric's entry in the [Metrics Catalogs Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}}). Select the "Index" button to access the list of all available metrics and jump directly to that item in the catalog.{{< /tip >}} |
+| `period` | Defines the time window in which you want to calculate the aggregated metric value. - The maximum possible time window is `24h`. - The minimum possible time window is `2m`.|
+| `filter` | Lets you refine the alert rule for a more specific set of metric values, based on dimensions. If no filter is provided, all collected data will be used when calculating the alert rule status.|
+| `group by` | Groups results according to the specified dimension(s). A separate alert will be triggered for each result group. You can provide multiple dimension names as a comma-separated list. {{}}Using a dimension with a high cardinality of values might result in a high volume of alerts.{{}}|
+| `notification type` | Defines how you want to receive alert notifications. |
+| `email addresses` | A comma-separated list of email addresses that should receive alert notifications.|
+| `mute` | Boolean; turns alert notifications on and off. Set to 'on' to mute notifications. |
+
+If you leave any rule parameter blank, NGINX Controller will take all relevant data for the parameter into account in the alert rule calculation.
+
+Each Alert Rule has a status that describes the current state of the alert rule. It contains the following information:
+
+
+
+
+
+| Name | Description |
+|---|---|
+| `alerts count` | The total number of triggered alerts for the Alert Rule since its creation.|
+| `status: ok` | The rule has not triggered any alerts, or that all triggered alerts have expired.|
+| `status: ongoing` | At least one alert for the alert rule is currently ongoing.|
+| `lastCheckedTimestamp` | The time when the alert rule was last checked successfully.|
+| `lastStartedTimestamp` | The time when alert rule status has changed from 'ok' to 'ongoing'.|
+| `lastExpiredTimestamp` | The time when alert rule status has changed from 'ongoing' to 'ok'.|
+
+
+
+Alert rules work in the following manner:
+
+1. Incoming metric updates are continuously monitored against the set of alert rules.
+2. The most recent metric value is checked against the threshold defined in the alert rule.
+3. If the threshold is met, an alert notification is generated and the rule will continue to be monitored. In the [Alerts Status]({{< relref "/controller/analytics/alerts/manage-alerts.md#view-alert-rule-status" >}}) pane, the alert instance's status will be displayed as "ongoing".
+4. If subsequent metric updates show that the metric no longer violates the threshold for the configured period, the alert expires.
+
+## Alert Notifications
+
+An *Alert notification* is a message either displayed in the NGINX Controller user interface or sent via email. Alert notifications are sent when an alert is triggered or expired, depending on the alert rule criteria.
+
+- The **Notifications** feed contains information about all changes in the system, including alert changes. To access the Notifications feed, select the bell icon next to the **Account Settings** menu.
+- A notification appears in the Notifications feed immediately when an alert is triggered or expires.
+- Alert instance emails notify you when a single alert instance starts or expires.
+
+If you want to stop receiving notifications for an alert rule, but you don't want to delete it, you can [mute the alert rule]({{< relref "/controller/analytics/alerts/manage-alerts.md#mute-or-unmute-an-alert-rule" >}}).
+Likewise, if you want to stop receiving emails for an alert rule, but you do want to continue receiving the user interface notifications, [edit the alert rule]({{< relref "/controller/analytics/alerts/manage-alerts.md#edit-an-alert-rule" >}}) and remove your email address.
+
+{{< note >}}If you mute an alert rule while the alert rule status is "ongoing", you will not receive any further alert notifications, including when the alert rule status changes.{{< /note >}}
+
+### Email notifications
+
+{{< important >}}
+You must [verify your email address]({{< relref "/controller/analytics/alerts/manage-registered-emails.md" >}}) in order to receive alert notification emails.
+{{< /important >}}
+
+When an alert rule's conditions are met, NGINX Controller sends an alert email with the subject "[controller-alert] Alert started: " to all of the email addresses that are specified in the alert rule.
+
+If multiple alerts are triggered in a single calculation period, NGINX Controller sends a summary email message that contains all of the alerts for the time period.
+
+When an alert instance expires, NGINX Controller sends a message with subject "[controller-alert] Alert expired: " to all of the email addresses that are specified in the alert rule.
+
+The notification uses the automatically-generated name that was assigned by the system when the rule was created.
+
+NGINX Controller sends summary emails once every hour. These emails contain alerts that have been triggered or expired since the last summary email was sent. If no alerts started or expired in that timeframe, then the summary will not be sent.
+
+### How Many Notifications to Expect
+
+As an example, let's say that you have three instances configured in the NGINX Controller. You want to monitor all three instances based on the `http.request.count` metric.
+
+Assuming that traffic is constantly flowing through all three instances, and the threshold is exceeded for all three, the system will return three alerts (one per instance). In this case, you would receive one email, containing three alert notices, and three user interface notifications.
+
+If the threshold is exceeded for one instance, then you will receive one alert email and one notification in the user interface.
+
+## How Alerts Work
+
+NGINX Controller checks the list of configured alert rules every 30 seconds. Then, it queries the [Metrics API]({{< relref "/controller/analytics/metrics/metrics-api.md" >}}) for the data defined in each alert rule.
+
+The API query uses the following template:
+
+`?names=()&startTime=now-&endTime=now<&additional-alert-rule-parameters>"`
+
+where
+
+- `` is the appropriate [aggregation function]({{< relref "/controller/analytics/metrics/metrics-api.md#aggregations" >}}) for the metric. You can find this information in the [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}}).
+ - `AVG` applies to `gauge` metrics. Gauges are averaged over the time period configured in the alert rule.
+ - `MAX` applies to `counter` metrics.
+ - `SUM` applies to `incremental` metrics.
+
+- The `` and `` parameters are read from the alert rule configuration.
+- `<&additional-alert-rule-parameters>` e.g. `filter` or `groupBy` parameters read from the alert rule configuration.
+
+NGINX Controller checks the value returned by the Metrics API against the configured threshold, then takes the appropriate action:
+
+
+
+| Conditions | Action |
+|---|---|
+| - threshold is exceeded - "ongoing" alert does not exist | Triggers new alert. |
+| - threshold is exceeded - "ongoing" alert exists | Updates existing alert's `last_checked_timestamp` and `last_checked_value`. |
+| - threshold *is not* exceeded - "ongoing" alert exists | Expires alert.|
+| - threshold *is not* exceeded - "ongoing" does not exist | No action.|
+
+Next, the alert rule status is updated. Each alert rule will be updated with a new `last_checked_timestamp` and new `status`, if applicable.
+
+Finally, the alert notifications for newly-created or expired alerts will be sent for any rules that are not muted.
+
+{{< important >}}
+If the [Metrics API]({{< relref "/controller/analytics/metrics/metrics-api.md" >}}) query does not return any data -- for example, if there was no traffic through the instance and therefore no metric value -- NGINX Controller assumes a value of `0`. In such cases, the threshold will be compared to `0`.
+{{< /important >}}
+
+## Alert special cases
+
+### Alerts for the controller.agent.status metric
+
+The `controller.agent.status` is a special metric representing the heartbeat of the NGINX Agent running on the instance.
+The metric is reported every 1 minute by the NGINX Agent to the NGINX Controller and may only have a value of 1 if the NGINX Agent is healthy.
+If the NGINX Agent is unhealthy it is not reporting the heartbeat and effectively no values for the `controller.agent.status` are stored by the NGINX Controller.
+Based on this metric it is possible to create an alert rule and receive notifications whenever the total number of heartbeats reported by a certain NGINX Agent in a recent period is below or equal (or above or equal) certain threshold.
+
+For example, you would like to receive notifications whenever the NGINX Agent availability at any instance is less or equal 70%.
+To achieve that:
+
+1. Create an alert rule for the `controller.agent.status` metric.
+2. Set the period to at least 10 minutes (recommended, to avoid flapping conditions). Heartbeats arrive every minute while the alert status is evaluated every 30 seconds.
+3. Set the threshold to 7 of the NGINX Agent availability (7 heartbeats received in the last 10 min).
+4. Set the operator to below or equal.
+5. Break out by the instance dimension to get notified about the NGINX Agent availability per instance.
+
+## What's Next
+
+- [Create and Manage Alert Rules]({{< relref "/controller/analytics/alerts/manage-alerts.md" >}})
+- [Manage Registered Emails]({{< relref "/controller/analytics/alerts/manage-registered-emails.md" >}})
+- [NGINX Controller REST API Reference]({{< relref "/controller/api/_index.md" >}})
+
+{{< versions "3.13" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/alerts/manage-alerts.md b/content/controller/analytics/alerts/manage-alerts.md
new file mode 100644
index 000000000..746390e08
--- /dev/null
+++ b/content/controller/analytics/alerts/manage-alerts.md
@@ -0,0 +1,104 @@
+---
+description: Learn how to view, add, mute, and delete Alerts.
+docs: DOCS-521
+doctypes:
+- concept
+tags:
+- docs
+title: Manage Alerts
+toc: true
+weight: 200
+---
+
+## Overview
+
+[Alerts]({{< relref "/controller/analytics/alerts/about-alerts.md" >}}) are notifications about the F5 NGINX Controller system and your applications' performance.
+
+[Alert rules]({{< relref "/controller/analytics/alerts/about-alerts.md#alert-rules" >}}) let you specify what you want to be alerted about. This includes which metrics you want to monitor; the trigger conditions and threshold to meet; the instance(s) to monitor; and the email address(es) to use for notifications.
+
+## Add an Alert Rule
+
+To add an alert rule:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Alerts > Alert Rules**.
+1. Select **Create Alert Rule**.
+1. Define your alert rule by providing the following information:
+
+ - Name
+ - (Optional) Display Name
+ - Metric
+ - Condition, Threshold, and Time Period
+ - Filter
+ - (Optional) Breakout
+ - Email Notification Address(es):
+
+ - Select the desired address(es) from the list provided, or
+ - Select **Manage Email Addresses** to add a new address, then take the steps below:
+
+ 1. Select **Add Email Address**.
+ 1. Provide the desired email address.
+ 1. Select the submit (plus sign) icon.
+ 1. Select **Done** to close the Manage Email Addresses panel.
+
+ {{}}You will need to verify the email address before it can begin receiving alerts.{{}}
+
+1. (Optional) Select **Mute Alert Rule** if you want to create the alert rule but not receive any associated notifications.
+1. Select **Create**.
+
+## View Alerts
+
+To view all **alerts** that are triggered by alert rules:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Alerts > Alerts**.
+
+All alert rules and triggered alerts are displayed on this page. You can use the search bar to filter the alerts that are displayed.
+
+## Edit an Alert Rule
+
+To edit an alert:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Alerts > Alert Rules**.
+1. Select the alert rule that you want to edit.
+1. Select the edit (pencil) icon for the alert rule.
+1. Make the desired changes to the alert rule, then select **Save**.
+
+{{< important >}}
+When you edit an alert rule, any ongoing alerts which previously met that rule will expire immediately.
+
+If the threshold is still exceeded in the new alert rule configuration, new alerts will be triggered.
+{{< /important >}}
+
+## Mute or Unmute an Alert Rule
+
+If you want to stop receiving notifications for an alert rule without deleting it, you can mute it. Likewise, you can unmute alert rules for which you want to resume receiving notifications.
+
+To mute or unmute an alert:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Alerts > Alert Rules**.
+1. Select the alert rule that you want to mute or unmute.
+1. Select the mute (volume) icon to mute or unmute the alert rule.
+
+## Delete an Alert Rule
+
+To delete an alert rule:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Alerts > Alert Rules**.
+1. Select the alert rule that you want to delete.
+1. Select the delete (trash can) icon to delete the alert rule.
+1. Select **Delete** in the pop-up box to confirm that you want to proceed.
+
+## What's Next
+
+- Learn more [About Alerts]({{< relref "/controller/analytics/alerts/about-alerts.md" >}})
+- Learn more about [Metrics and Metadata]({{< relref "/controller/analytics/metrics/overview-metrics-metadata.md" >}})
+- Learn more about [Traffic Metrics]({{< relref "/controller/analytics/metrics/overview-traffic-metrics.md" >}})
+- [Manage Registered Emails]({{< relref "/controller/analytics/alerts/manage-registered-emails.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/alerts/manage-registered-emails.md b/content/controller/analytics/alerts/manage-registered-emails.md
new file mode 100644
index 000000000..f21d815a6
--- /dev/null
+++ b/content/controller/analytics/alerts/manage-registered-emails.md
@@ -0,0 +1,71 @@
+---
+description: Learn how to manage the email addresses that receive automatic alert
+ notifications.
+docs: DOCS-522
+doctypes:
+- concept
+tags:
+- docs
+title: Manage Registered Email Addresses
+toc: true
+weight: 310
+---
+
+## Overview
+
+In order to receive email notifications for [Alerts]({{< relref "/controller/analytics/alerts/about-alerts.md" >}}), you need to provide a valid email address and complete the verification process.
+
+{{< important >}}
+You will not receive any alert notifications via email until you verify your email address. Any alert notification emails that were triggered by alert rules prior to the email address being verified will not be re-sent.
+{{< /important >}}
+
+## List Registered Email Addresses
+
+To find the list of registered email addresses:
+
+1. Open the F5 NGINX Controller user interface and log in.
+1. On the **Analytics** menu, select **Alerts**.
+1. On the **Alert Rules Overview** page, select **Manage Email Addresses**.
+1. All registered email addresses are displayed in the Manage Email Addresses panel. To close the panel, select **Done**.
+
+{{}}The **Manage Email Addresses** button is not displayed if you don't have any Alerts configured. If this is the case, you can add a new email address when you [create an alert rule]({{< relref "/controller/analytics/alerts/manage-alerts.md#add-an-alert-rule" >}}).{{}}
+
+## Add a New Email Address
+
+To add a new email address:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the **Analytics** menu, select **Alerts**.
+1. On the **Alert Rules Overview** page, select **Manage Email Addresses**.
+1. In the **Manage Email Addresses** panel:
+1. Select **Add Email Address**.
+1. Provide the desired email address.
+1. Select the submit (plus sign) icon.
+1. Select **Done** to close the Manage Email Addresses panel.
+1. Check your email inbox for a message with the subject `[controller-team] Email verification`.
+1. Click on the link provided in the email to complete the verification process.
+
+## Re-send a Verification Email
+
+To re-send a verification email to a newly-registered email address:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the **Analytics** menu, select **Alerts**.
+1. On the **Alert Rules Overview** page, select **Manage Email Addresses**.
+1. Select the Resend verification (circular arrows) icon to the right of the email address.
+1. Select **Done** to close the Manage Email Addresses panel.
+
+## Remove a Registered Email Address
+
+To remove a registered email address:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the **Analytics** menu, select **Alerts**.
+1. On the **Alert Rules Overview** page, select **Manage Email Addresses**.
+1. On the **Manage Email Addresses** panel, select the Delete email address (trash can) icon to the right of the email address that you want to remove.
+1. In the **Delete Email Address** pop-up window, select **Delete** to confirm.
+1. Select **Done** to close the Manage Email Addresses panel.
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/alerts/service-now-notifications.md b/content/controller/analytics/alerts/service-now-notifications.md
new file mode 100644
index 000000000..f14ff27cc
--- /dev/null
+++ b/content/controller/analytics/alerts/service-now-notifications.md
@@ -0,0 +1,57 @@
+---
+description: Set up Alerts Integration with ServiceNow. Deprecated in v3.13.
+docs: DOCS-523
+doctypes:
+- task
+tags:
+- docs
+- deprecated
+title: ServiceNow Alerts Integration
+toc: true
+weight: 600
+---
+
+## ServiceNow Alert Integration
+
+{{< deprecated >}}
+**The ServiceNow Alert Integration is deprecated in F5 NGINX Controller v3.13.**
+{{< /deprecated >}}
+
+The ServiceNow integration sends all notifications from NGINX Controller to the Incidents table in your ServiceNow account. Follow the steps below to set up the integration.
+
+1. Install Python3 on your machine.
+2. In your ServiceNow instance, go to **System OAuth > Application Registry** and create a new OAuth API endpoint for external clients.
+
+ Fill out the form and specify a long refresh token lifespan. Consider aligning the token lifespan with the expiry date of your NGINX Controller license.
+
+ {{< important >}} The ServiceNow integration will fail once the refresh token expires.{{< /important >}}
+
+3. Select the **Configure ServiceNow** button. In the prompt, provide the requested information for the ServiceNow client and select **Save**.
+
+ - **ServiceNow Instance** - The instance ID for your ServiceNow account.
+ - **Client ID** - Client ID from ServiceNow (from Step 2).
+ - **Client Secret** - Client Secret from ServiceNow (from Step 2).
+ - **Username** - Your ServiceNow username; this is used to generate the access token and will not be stored.
+ - **Password** - Your ServiceNow password; this is used to generate the access token and will not be stored.
+ - **Controller host** - The URL of your NGINX Controller instance.
+ - **Controller email** - The email that you use to log in to Controller.
+ - **Controller password** - The password that you use to log in to Controller.
+ - **Controller port** - The port on which NGINX Controller is running; the default is 80.
+ - **Company name** - The name of your company; this is used to create the ServiceNow transport.
+
+4. Watch Controller alerts come through as incidents in ServiceNow.
+
+ Mapping of Controller Alerts to ServiceNow Priority:
+
+ - ('alerts', 'created') → 1
+ - ('alerts', 'cleared') → 3
+ - ('agent', 'nginx_not_found') → 1
+ - ('agent', 'nginx_config_parsing_error') → 1
+ - ('ssl_expiration', 'ssl_cert_has_expired') → 1
+ - ('ssl_expiration', 'ssl_cert_will_expire') → 2
+ - ('agent', 'agent_version_old') → 2
+ - ('agent', 'agent_version_obsoleted') → 1
+ - ('group_actions', 'group_action_completed') → 3
+
+{{< versions "3.0" "3.13" "ctrlvers" >}}
+
diff --git a/content/controller/analytics/catalogs/_index.md b/content/controller/analytics/catalogs/_index.md
new file mode 100644
index 000000000..42f5a7ff3
--- /dev/null
+++ b/content/controller/analytics/catalogs/_index.md
@@ -0,0 +1,13 @@
+---
+aliases:
+- /analytics/dimensions/reference/
+- /analytics/metrics/reference/
+description: Reference information for F5 NGINX Controller Catalogs.
+menu:
+ docs:
+ parent: Analytics
+ weight: 20
+title: Catalogs Reference
+weight: 210
+url: /nginx-controller/analytics/catalogs/
+---
diff --git a/content/controller/analytics/catalogs/dimensions.md b/content/controller/analytics/catalogs/dimensions.md
new file mode 100644
index 000000000..dbf884d61
--- /dev/null
+++ b/content/controller/analytics/catalogs/dimensions.md
@@ -0,0 +1,19 @@
+---
+catalog: true
+description: Information about all of the Dimensions collected by F5 NGINX Controller
+ Agent.
+docs: DOCS-524
+doctypes:
+- reference
+tags:
+- docs
+title: NGINX Controller Dimensions Catalog
+toc: false
+weight: 20
+---
+
+{{< dimensions path="/static/ctlr/catalogs/dimensions-catalog.json" >}}
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/catalogs/metrics.md b/content/controller/analytics/catalogs/metrics.md
new file mode 100644
index 000000000..39e167b92
--- /dev/null
+++ b/content/controller/analytics/catalogs/metrics.md
@@ -0,0 +1,18 @@
+---
+catalog: true
+description: Information about all of the Metrics collected by F5 NGINX Controller Agent.
+docs: DOCS-525
+doctypes:
+- reference
+tags:
+- docs
+title: NGINX Controller Metrics Catalog
+toc: false
+weight: 20
+---
+
+{{< metrics path="/static/ctlr/catalogs/metrics-catalog.json" >}}
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/dashboards/_index.md b/content/controller/analytics/dashboards/_index.md
new file mode 100644
index 000000000..8b6ae2a58
--- /dev/null
+++ b/content/controller/analytics/dashboards/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn about F5 NGINX Controller Dashboards.
+menu:
+ docs:
+ parent: Analytics
+ weight: 40
+title: Dashboards
+weight: 120
+url: /nginx-controller/analytics/dashboards/
+---
diff --git a/content/controller/analytics/dashboards/application-health-score.md b/content/controller/analytics/dashboards/application-health-score.md
new file mode 100644
index 000000000..135b78d2c
--- /dev/null
+++ b/content/controller/analytics/dashboards/application-health-score.md
@@ -0,0 +1,95 @@
+---
+description: View and understand the Application Health Score for your application.
+docs: DOCS-526
+doctypes:
+- concept
+tags:
+- docs
+title: Understanding the Application Health Score
+toc: true
+weight: 20
+---
+
+## Overview
+
+When you log in to the F5 NGINX Controller user interface, you will see the **Analytics Dashboard Overview** page. This page contains an Application Health Score (AHS) that reflects your application's performance.
+
+The AHS is a customizable [Apdex-like numerical measure](https://www.apdex.org/) that can be used to estimate the quality of experience for your web application. It lets you configure service-level monitoring for your applications.
+
+You can select any combination of the following three service-level indicators (SLI) to create your AHS:
+
+- Successful requests (selected by default),
+- (Optional) Request time (95th percentile), and
+- (Optional) NGINX Controller Agent availability.
+
+Successful requests are determined according to the total observed average request time (P95) either below the low threshold (100% satisfying) or between the low and high threshold (partially satisfying).
+
+A simplified formula for AHS is as follows:
+
+`AHS = (Successful Requests %) * (Timely Requests %) * (Agent Availability %)`
+
+When you select the Request Time (95th percentile) for inclusion in the AHS, you can set two thresholds for the total observed average request time (P95):
+
+- Low threshold for satisfying requests.
+- High threshold for partially satisfying requests.
+
+If the average request time (P95) for the selected time period is below the low threshold, this is considered as a "100% satisfying" state of requests.
+
+If the request time is above the low threshold and below the high threshold, a "satisfaction ratio" is calculated accordingly.
+Requests above the high threshold are considered to be "0%", or "unsatisfying".
+
+For example: If the low threshold is 0.2s and the high threshold is 1s, a request time greater than 1s would be considered unsatisfying and the resulting score would be 0%.
+
+The algorithm for calculating the AHS is as follows. Here, `T1` represents the low threshold and `T2` represents the high threshold.
+
+```nginx
+successful_req_pct = (nginx.http.request.count - nginx.http.status.5xx) / nginx.http.request.count
+
+if (nginx.http.request.time.pctl95 < T1)
+ timely_req_pct = 1
+else
+ if (nginx.http.request.time.pctl95 < T2)
+ timely_req_pct = 1 - (nginx.http.request.time.pctl95 - T1) / (T2 - T1)
+ else
+ timely_req_pct = 0
+
+m1 = successful_req_pct
+m2 = timely_req_pct
+m3 = agent_up_pct
+
+app_health_score = m1 * m2 * m3
+```
+
+## Customize the Application Health Score
+
+Take the steps below to customize the Application Health Score (AHS) that displays on the Overview page.
+
+{{< note >}}
+By default, the AHS and other metrics on the **Overview** page are calculated for all of the Instances monitored by the Controller Agent.
+{{< /note >}}
+
+1. Open the NGINX Controller user interface and log in.
+2. On the **Overview** page, select the Settings (gear) icon in the Application Health Score panel.
+3. In the **Service Level Monitoring** window, define the following:
+
+ - (Optional) Create a custom name for the monitor (replaces "Application Health Score").
+ - (Optional) Select tags to narrow the data source(s) to a specific Instance or set of Instances.
+ - Select the Service Indicators that you want to include in the score calculation.
+
+ - Successful requests (selected by default).
+ - Request time (95th percentile): Set a low threshold and a high threshold, in seconds.
+ - Agent availability.
+
+4. Select **Save**.
+
+## What's Next
+
+- [Overview of metrics and metadata]({{< relref "/controller/analytics/metrics/overview-metrics-metadata.md" >}})
+- [Set up Metrics Collection]({{< relref "/controller/admin-guides/config-agent/configure-metrics-collection.md" >}})
+- [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}})
+- [Dimensions Catalog Reference]({{< relref "/controller/analytics/catalogs/dimensions.md" >}})
+- [Custom Dashboards]({{< relref "/controller/analytics/dashboards/custom-dashboards.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/dashboards/custom-dashboards.md b/content/controller/analytics/dashboards/custom-dashboards.md
new file mode 100644
index 000000000..de2458940
--- /dev/null
+++ b/content/controller/analytics/dashboards/custom-dashboards.md
@@ -0,0 +1,141 @@
+---
+description: Create custom dashboards to view custom graphs.
+docs: DOCS-527
+doctypes:
+- task
+tags:
+- docs
+title: Create Custom Dashboards
+toc: true
+weight: 20
+---
+
+## Overview
+
+You can use the F5 NGINX Controller user interface to create your own Dashboards populated with customizable graphs of NGINX and system-level metrics.
+
+{{< note >}}
+
+- You can add up to 30 Elements to Dashboard.
+- Dashboards are accessible by all Users.
+
+{{< /note >}}
+
+## Before You Begin
+
+- [Install the NGINX Controller Agent on instances that you want to monitor]({{< relref "/controller/admin-guides/install/install-nginx-controller-agent.md" >}})
+- [Configure Metrics collection on your NGINX instances]({{< relref "/controller/admin-guides/config-agent/configure-metrics-collection.md" >}})
+
+## Dashboards
+
+In NGINX Controller, you can create dashboards to display custom graphs. Some use cases for custom graphs include the following:
+
+- Checking NGINX performance for a particular application or microservice, for example, based on the URI path
+- Displaying metrics per virtual server
+- Visualizing the performance of a group of NGINX servers, for example, front-end load-balancers or an NGINX edge caching layer
+- Analyzing a detailed breakdown of HTTP status codes per application
+
+When building a custom graph, metrics can be summed or averaged across NGINX servers. By using metric filters, it is possible to create additional "metric dimensions", for example, reporting the number of POST requests for a specific URI.
+
+ {{< note >}}
+
+The functionality of user-defined dashboards recently changed in NGINX Controller. Some of the functionalities that were present in the
+previous version might not be currently present or work differently. Your old dashboards were not migrated to the new version.
+
+ {{< /note >}}
+
+## Create a Custom Dashboard
+
+To create a custom dashboard:
+
+1. Open the NGINX Controller user interface and log in.
+2. The first page you will see is the **Analytics Overview** page.
+3. Select the Dashboards tab to see the **My Dashboards** list page.
+4. To create a new dashboard - use **Create** button and provide required information.
+
+### Add a Dashboard Element
+
+To add an Element to a Dashboard:
+
+1. Create a new Dashboard or select the edit icon to edit an existing Dashboard.
+2. Select **Add element** button.
+3. Provide a title.
+4. (Optional) Enter a description of the Element.
+5. Select the type of Element to add:
+
+ - **Line chart** displays data for a specific time period
+ - **Stat** displays the metric's most recent value
+
+6. Select a metric from the drop-down menu.
+7. Select the aggregation method for the selected metric.
+ {{< see-also >}}
+For more information about metrics and supported aggregation methods, see the [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}}).
+ {{< /see-also >}}
+8. (Optional) Add a filter to refine the data. For example, you can limit the data to a specific App or Environment.
+9. (Optional) Select **Add metrics** to add more metrics.
+ {{< note >}}
+Additional metrics can only be added to a **Line chart** Element.
+ {{< /note >}}
+10. (Optional) Select the **Override Default Time Settings** option to select a time range for the Element.
+
+ - The default time range is the last seven days.
+ - You can select a new pre-defined time range or select **Custom time range** to define a new time range.
+
+11. Select **Create** or **Edit** to save your Element settings.
+
+## Filter Metrics
+
+You can use the filtering functionality for NGINX metrics. If you select **Add filter**, you can add multiple criteria to define specific "metric dimensions".
+
+The filter consists of one or more expressions in a form of:
+
+`dimensionName operator value`
+
+where:
+
+- `dimensionName` is a name of the dimension from the dimensions catalog
+- `operator` is a comparison rule (equality, likeliness, etc.)
+- `value` is a value to which we want compare the dimensions value
+
+Filters can be used in conjunction using `AND` or `OR` logical operators. There is no possibility of nesting these expressions.
+
+Filters are used to narrow down the data set presented on the chart/stat. For example, you may not want to display the data for all of your applications, but only for the particular one.
+
+## Limitations
+
+- You are not able to add more than 30 elements to the single dashboard.
+- All dashboards are accessible for all users.
+- Dashboards defined in the old custom dashboards view are not migrated to the new dashboards view.
+
+## Clone a Custom Dashboard
+
+To clone an existing dashboard from the Dashboards page, select the **Clone** icon on a dashboard's row, or select **Clone** from the toolbar above the table (you need to select a dashboard first).
+
+You can also clone a dashboard from the elements view using the **Clone Dashboard** button. This button is not available in "edit" mode, so make sure you finish editing a dashboard before cloning it.
+
+When you clone a dashboard, the new one will have the same display name as the original dashboard + the current date. For example, if you clone the "My system graphs" dashboard, the cloned dashboard's display name will be something like "My system graphs Aug 24, 2021, 14:37:32". You can change the display name later on the Edit Config page.
+
+## Predefined Dashboards
+
+You can find predefined dashboards on the Dashboards page. Predefined dashboards have a special "Read Only" tag, include elements to show the most common metrics, and cover some common cases. The predefined dashboards might be helpful in learning how custom dashboards work. You can clone any of the predefined dashboards and then modify them as needed.
+
+Predefined dashboards cannot be deleted or modified.
+
+{{< note >}}
+
+- Predefined dashboards were introduced in NGINX Controller 3.21.
+- If you already have custom dashboards, the predefined ones should appear at the end of the list when default sorting is applied.
+
+{{< /note >}}
+
+## What's Next
+
+- [Overview Dashboard]({{< relref "/controller/analytics/dashboards/overview-dashboard.md" >}})
+- [Overview of Metrics and Metadata]({{< relref "/controller/analytics/metrics/overview-metrics-metadata.md" >}})
+- [Set up Metrics Collection]({{< relref "/controller/admin-guides/config-agent/configure-metrics-collection.md" >}})
+- [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}})
+- [Dimensions Catalog Reference]({{< relref "/controller/analytics/catalogs/dimensions.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/dashboards/overview-dashboard.md b/content/controller/analytics/dashboards/overview-dashboard.md
new file mode 100644
index 000000000..fa1467bd3
--- /dev/null
+++ b/content/controller/analytics/dashboards/overview-dashboard.md
@@ -0,0 +1,67 @@
+---
+description: Learn about the Dashboards that displays cumulative metrics for your
+ NGINX Instances.
+docs: DOCS-528
+doctypes:
+- task
+tags:
+- docs
+title: Analytics Overview
+toc: true
+weight: 10
+---
+
+## Overview
+
+The **Analytics Dashboards** provides an at-a-glance summary of the state of your F5 NGINX infrastructure and your application performance.
+
+## Before You Begin
+
+- [Install the NGINX Controller Agent on Instances that you want to monitor]({{< relref "/controller/admin-guides/install/install-nginx-controller-agent.md" >}})
+
+## Overview Dashboard
+
+When you log in to the NGINX Controller user interface, the **Analytics Overview** page displays first by default. Select the Dashboards tab to see the **My Dashboards** list page. On the **Dashboard Overview** page, you can view the key indicators noted below. By default, the graphs display metrics for the last hour. You can select any of the default time periods -- one hour, four hours, one day, two days, or one week -- to get a better idea of your apps' overall health and performance. To view metrics over longer time periods, you can create a [custom dashboard]({{< relref "/controller/analytics/dashboards/custom-dashboards.md" >}}).
+
+The cumulative [metrics]({{< relref "/controller/analytics/metrics/overview-metrics-metadata.md" >}}) displayed on the **Analytics Overview** page are:
+
+### System Metrics
+
+- [Application Health Score]({{< relref "/controller/analytics/dashboards/application-health-score.md" >}}): the health score for your application.
+- Average CPU: 100 - AVG of the system.cpu.idle (CPU spent in an idle state)
+- Average Memory: AVG of the `system.mem.used` metric
+
+### Application Metrics
+
+- Time to First Byte: AVG of the `client.ttfb.latency.max` metric
+- Bytes In/s (Bytes In per second): RATE of the `http.request.bytes_rcvd` metric
+- Bytes Out/s (Bytes Out per second): RATE of the `http.request.bytes_sent` metric
+
+- Total Requests: SUM of the `nginx.http.request.count` metric.
+- HTTP 5XX Errors: SUM of the `nginx.http.status.5xx` metric.
+- HTTP 4XX Errors: SUM of the `nginx.http.status.4xx` metric.
+- Request time (P95): AVG of the `nginx.http.request.time.pctl95` metric.
+
+- Avg Client Response Latency: AVG of the `client.response.latency.max` metric
+- Avg Upstream Response Latency: AVG of the `upstream.response.latency.max` metric
+- Avg Client Network Latency: AVG of the `client.network.latency.max` metric.
+
+{{< note >}}
+
+By default, the metrics are calculated for **all** of your Controller Agent-monitored Instances.
+
+To display metrics for a specific set of hosts (for example, only for "production"), select the gear icon on the Application Health Score panel, then add a tag or tags by which you want to filter the results.
+
+{{< /note >}}
+
+## What's Next
+
+- [Overview of metrics and metadata]({{< relref "/controller/analytics/metrics/overview-metrics-metadata.md" >}})
+- [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}})
+- [Dimensions Catalog Reference]({{< relref "/controller/analytics/catalogs/dimensions.md" >}})
+- [Application Health Score]({{< relref "/controller/analytics/dashboards/application-health-score.md" >}})
+- [Custom Dashboards]({{< relref "/controller/analytics/dashboards/custom-dashboards.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/data-explorer/_index.md b/content/controller/analytics/data-explorer/_index.md
new file mode 100644
index 000000000..59a5fefb5
--- /dev/null
+++ b/content/controller/analytics/data-explorer/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn about F5 NGINX Controller Data Explorer.
+menu:
+ docs:
+ parent: Analytics
+ weight: 40
+title: Data Explorer
+weight: 120
+url: /nginx-controller/analytics/data-explorer/
+---
diff --git a/content/controller/analytics/data-explorer/how-to-use.md b/content/controller/analytics/data-explorer/how-to-use.md
new file mode 100644
index 000000000..6c77eb329
--- /dev/null
+++ b/content/controller/analytics/data-explorer/how-to-use.md
@@ -0,0 +1,150 @@
+---
+description: Use the Data Explorer to examine the metrics that F5 NGINX Controller collects.
+docs: DOCS-529
+doctypes:
+- task
+tags:
+- docs
+title: How To Use the Data Explorer
+toc: true
+weight: 20
+---
+
+## Overview
+
+This topic explains how to use the Data Explorer to view the metrics that F5 NGINX Controller collects.
+
+The Data Explorer lets you perform these following tasks:
+
+- Easily switch between contexts, metrics, and dimensions
+- Specify a time range of interest
+- Set the aggregation mode
+- Compare results to previous periods
+- Export the query that's used to generate the charts as a URL, which you can use outside of NGINX Controller
+
+
+
+## Select the Context
+
+To get started with the Data Explorer, you need to select the context for the data you want to view.
+
+1. Open the NGINX Controller user interface and log in.
+1. Select the NGINX Controller menu icon, then select **Analytics > Explorer**.
+1. On the Data Explorer detail page, select a context area -- **Instances**, **Environments**, **Gateways**, or **Apps** -- for which you want to view data.
+
+{{< note >}}
+When you access the Data Explorer from other areas of the browser interface, the context is already defined. So, for example, if you select Data Explorer from within the Instances module (**Infrastructure > Instances > Data Explorer**), the data for your instances is displayed. When you switch between contexts, the metrics options, such as `system.cpu.idle` or `system.load.5`, are updated.
+{{< /note >}}
+
+
+
+## Select a Resource
+
+When you [select the context](#select-the-context) for the Data Explorer, a list of related resources is shown. If there aren't any related resources for the selected context, you'll see the message "No Data" on the Data Explorer detail page.
+
+{{< note >}}
+
+If you don't see a resource in the list, but you expect it to be there, check the [selected metric](#metrics) and the [selected time range](#time-range). When a resource doesn't have the data for the [selected time range](#time-range) it won't be added to the resources list.
+
+{{< /note >}}
+
+To view data for a resource, select the resource's name from the resource list.
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_resource.png">}}
+
+## Metrics
+
+The [list of metrics]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) is sorted alphabetically, and you can use the search feature to filter the list. As previously mentioned, the list of metrics depends on the context you've selected for the Data Explorer. For example, if you've chosen Instances for the context, then the list of metrics will be for instances.
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_metric.png">}}
+
+When the selected metric changes, the **Aggregation** and **Group By** selectors are updated correspondingly (as well as the [list of resources](#select-a-resource) and the [Dimensions panel](#dimensions-panel)). Some metrics have different lists of **Aggregation** and **Group By** values. For example, the `http.response_code` dimension, which is a valid **Group By** value for the `http.request.count` metric, is not available for the `nginx.workers.cpu.user` metric because these items are from different contexts and aren't related to each other.
+
+## Aggregation Mode
+
+Use the Aggregation selector -- the Σ symbol with possible values of `AVG`, `MAX`, `MIN`, `RATE`, and `SUM` -- to [aggregate the data]({{< relref "/controller/analytics/metrics/metrics-api.md#aggregations" >}}). The list of possible aggregation values depends on the metrics that's selected.
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_aggregation.png">}}
+
+## Group by Dimension
+
+Use the **Group By** selector to [group the data by a chosen dimension]({{< relref "/controller/analytics/metrics/metrics-api.md#groupby" >}}).
+
+In the following example image, the data for the `bytes_rcvd` metric is grouped by the dimension `http.request_method`, which displays a data series for the HTTP methods `DELETE`, `GET`, `LINK`, and so on.
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_group-by.png">}}
+
+When a **Group By** selection is applied, the chart displays a top-10 data series. For example, let's say you want to check disk usage, so you select the metric `system.disk.total` and `file_path` as the dimension to group by. The chart would then display the top-10 mount points with the highest values. If you have more than 10 mount points, you'll see the top-10 mount points plus an 11th data series that's an aggregation of the rest of the data using the same selection criteria. In other words, you'll see a chart of the 10 most used mount points plus a chart of all the other mount points aggregated into one data series. When a **Group By** dimension is selected, and there are more than 10 dimensions, the 11th data series is named "Other."
+
+{{< note >}} When MIN is selected as the aggregation method, the top-10 series are sorted ascending, lowest-to-highest. For all of the other aggregation methods, the top-10 values are sorted descending, highest-to-lowest. {{< /note >}}
+
+
+
+## Time Range
+
+Use the time range selector above the chart to select the time range you want to examine. You can specify a custom time range if the predefined options aren't what you need.
+
+The granularity of the data series is based on the selected time range and can vary from 30 seconds to five days to make the chart easier to read.
+
+When you change the time range, the [list of resources](#select-a-resource) is updated correspondingly and it only includes the resources which have the data for the selected time range.
+
+## Compare To
+
+Next to the [time range](#time-range) selector, you'll find the `Compare To` list of options. This list allows you to compare data for the selected time frame with data from an earlier period. For example, you may want to view CPU usage for the last hour and compare the results to the same time from yesterday, last week, or even the previous year.
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_comparison.png">}}
+
+{{< note >}}
+
+- When comparison is turned on for a data series, the data have the suffix "Compare" in their names.
+- If there is no data available for a comparison period, the comparison data series is not shown.
+- When a Group By dimension is applied, data comparisons are made only with the top-10 data series and not with the "Other" series, if there is one. See the [Group By](#group-by) section for a discussion of the top-10 and "Other" series.
+{{< /note >}}
+
+
+
+## Show Query
+
+On the Data Explorer details page, you can select the **Show Query** button (eye icon) to view the URL that's used to query the Metrics API to get the data you see in the chart. If you copy the query and use it outside of NGINX Controller, you'll get the same data but in JSON format.
+
+The query updates whenever the selection options change. The query doesn't include requests for comparison data.
+
+{{< see-also >}}
+For instructions on how to understand the Metrics API response, refer to the topic [Using the Metrics API]({{< relref "/controller/analytics/metrics/metrics-api#understanding-the-metrics-api-response" >}}).
+{{< /see-also >}}
+
+
+
+## Dimensions panel
+
+On the right of the screen there is a panel with the list of dimensions available for the [selected metric](#metrics).
+
+{{< img src="/controller/analytics/data-explorer/images/data-explorer_dimensions-drawer.png">}}
+
+Each dimension is presented as a section in which you can expand and see the values for it. The values are aggregated with the [selected aggregation method](#aggregation-mode) for the [selected time range](#time-range). They depend on the following selected parameters:
+
+- [context](#select-the-context)
+- [resource](#select-a-resource)
+- [metric](#metrics)
+- [aggregation](#aggregation-mode)
+- [time range](#time-range)
+
+When one of the parameters changes, you'll see the values for expanded dimensions are also updated.
+
+You can see only top-10 values for each dimension, and based on the [selected aggregation](#aggregation-mode), they are sorted in following ways:
+
+- When MIN is selected as the aggregation method, the top-10 series are sorted ascending, lowest-to-highest.
+- For all of the other aggregation methods, the top-10 values are sorted descending, highest-to-lowest.
+
+{{< note >}}
+
+- When the selected metric changes, the list of dimensions may change as well, and some of the dimensions you recently explored may disappear from the panel.
+- This panel was added in NGINX Controller v3.18.
+
+{{< /note >}}
+
+
+
+{{< versions "3.17" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_aggregation.png b/content/controller/analytics/data-explorer/images/data-explorer_aggregation.png
new file mode 100644
index 000000000..9b529cd8e
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_aggregation.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_comparison.png b/content/controller/analytics/data-explorer/images/data-explorer_comparison.png
new file mode 100644
index 000000000..b9fe2ca29
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_comparison.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_dimensions-drawer.png b/content/controller/analytics/data-explorer/images/data-explorer_dimensions-drawer.png
new file mode 100644
index 000000000..e592fc3a5
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_dimensions-drawer.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_group-by.png b/content/controller/analytics/data-explorer/images/data-explorer_group-by.png
new file mode 100644
index 000000000..ed54fcac6
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_group-by.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_main-view.png b/content/controller/analytics/data-explorer/images/data-explorer_main-view.png
new file mode 100644
index 000000000..bdac1ddd7
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_main-view.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_metric.png b/content/controller/analytics/data-explorer/images/data-explorer_metric.png
new file mode 100644
index 000000000..abd160e34
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_metric.png differ
diff --git a/content/controller/analytics/data-explorer/images/data-explorer_resource.png b/content/controller/analytics/data-explorer/images/data-explorer_resource.png
new file mode 100644
index 000000000..1c2781260
Binary files /dev/null and b/content/controller/analytics/data-explorer/images/data-explorer_resource.png differ
diff --git a/content/controller/analytics/events/_index.md b/content/controller/analytics/events/_index.md
new file mode 100644
index 000000000..0dff2641d
--- /dev/null
+++ b/content/controller/analytics/events/_index.md
@@ -0,0 +1,10 @@
+---
+description: View system events and audit logs.
+menu:
+ docs:
+ parent: Analytics
+ weight: 30
+title: Events
+weight: 140
+url: /nginx-controller/analytics/events/
+---
diff --git a/content/controller/analytics/events/view-events.md b/content/controller/analytics/events/view-events.md
new file mode 100644
index 000000000..6e28bfb8c
--- /dev/null
+++ b/content/controller/analytics/events/view-events.md
@@ -0,0 +1,48 @@
+---
+description: View the audit log of system and user actions.
+docs: DOCS-530
+doctypes:
+- task
+tags:
+- docs
+title: View Events
+toc: true
+weight: 20
+---
+
+## Overview
+
+The Events page shows a log of the system and user actions for F5 NGINX Controller. The logs are organized by event categories and levels, making it easy to identify and review issues.
+
+## View Events
+
+Take the steps below to view NGINX Controller events:
+
+1. Open the NGINX Controller user interface and log in.
+1. On the Analytics menu, select **Events**.
+1. To view additional information about a particular event, select the event from the list to open the details pane.
+
+You can filter the events by typing a keyword in the search box and/or by selecting a time period. You can filter the results further by [Event Categories](#event-categories) or [Event Levels](#event-levels).
+
+## Event Categories
+
+You can select from the following Event Categories:
+
+- Agent Events;
+- Agent Status Events;
+- Controller Events;
+- Audit Events -- a log of all actions performed by NGINX Controller users;
+- Forwarder Notifications -- events emitted by [Data Forwarders]({{< relref "/controller/analytics/forwarders/_index.md" >}})
+- Workload Health Events -- events emitted by the Controller Agent when the health of an upstream server changes;
+
+To view the logs for a specific category, select the category name from the **Event Categories** list.
+
+## Event Levels
+
+Event levels sort events according to their information level: Debug, Info, Error, Warning, and Critical.
+
+To view the logs for a specific level, select the level name from the **Event Levels** list.
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/forwarders/_index.md b/content/controller/analytics/forwarders/_index.md
new file mode 100644
index 000000000..77ce17e24
--- /dev/null
+++ b/content/controller/analytics/forwarders/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn how to forward data from F5 NGINX Controller to external services.
+menu:
+ docs:
+ parent: Analytics
+ weight: 40
+title: Data Forwarders
+weight: 130
+url: /nginx-controller/analytics/forwarders/
+---
diff --git a/content/controller/analytics/forwarders/forward-analytics-to-datadog.md b/content/controller/analytics/forwarders/forward-analytics-to-datadog.md
new file mode 100644
index 000000000..098d33703
--- /dev/null
+++ b/content/controller/analytics/forwarders/forward-analytics-to-datadog.md
@@ -0,0 +1,77 @@
+---
+description: How to forward Analytics data to Datadog.
+docs: DOCS-531
+doctypes:
+- tutorial
+tags:
+- docs
+title: Forward Analytics Data to Datadog
+toc: true
+weight: 100
+---
+
+## Overview
+
+Follow the steps in this guide to set up an F5 NGINX Controller Integration that forwards data to [Datadog](https://www.datadoghq.com/).
+
+## Before You Begin
+
+This guide assumes that you are already an active Datadog user. If you haven't already done so, you will need to [install and configure Datadog](https://docs.datadoghq.com/) before you proceed.
+
+You will also need to [Create an Integration]({{< relref "/controller/platform/integrations/datadog-integration.md" >}}) for your Datadog forwarder.
+
+## Create a Forwarder
+
+Take the following steps to create a Forwarder for Datadog:
+
+1. Open the NGINX Controller user interface and log in.
+2. Select the NGINX Controller menu icon, then select **Platform**.
+3. On the **Platform** menu, select **Data Forwarders**.
+4. On the **Data Forwarders** menu, select the **Create Data Forwarder** quick action.
+5. Add a name.
+6. (Optional) Add a display name.
+7. (Optional) Add a description.
+8. Select your **Integration Reference** from the dropdown menu or select **Create New** to create a new Integration.
+9. In the **Collector Type** list, select `DATADOG`.
+10. In the **Source** list, select the type of data to forward: `metrics` or `events`.
+11. In the **Output Format** list, select `DATADOG`.
+12. The **Selector** field consists of the following query parameters (optional):
+
+- `names` (inapplicable for `EVENTS`): The list of metrics names that you want to forward.
+- `excluded_names` (inapplicable for `EVENTS`): The list of metric names that you don't want to forward.
+- `filter`: The conditions to use to refine the metrics or events data.
+- Example usage when selecting metrics: `"names=nginx.*&excluded_names=nginx.upstream.*filter=app='myapp'"`
+- Example usage when selecting events: `"filter=type='security violation' AND app='my-app'"`
+
+13. (Optional) Add additional **Streams** as required using the **Add Stream** button.
+
+{{< important >}}
+
+Each metric will be prefixed with a common namespace -- such as "nginx-controller" -- before it is sent to Datadog. This prefix is used by Datadog only and is not applied to any of the internal NGINX Controller metrics. Refer to the [metrics catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) for the full list of valid metric names.
+
+For events, the "nginx-controller" namespace is added to the ["ddsource" key](https://docs.datadoghq.com/api/v1/logs/#send-logs).
+
+{{< /important >}}
+
+NGINX Controller events are sent to Datadog as logs and NGINX Controller dimensions are sent as tags. The Forwarder converts the dimension data to comply with the Datadog [tags format](https://docs.datadoghq.com/getting_started/tagging/#defining-tags) prior to forwarding it. In some cases, the original dimension value may be transformed to fit the tag requirements. This includes replacing comma characters (`,`) with semicolons (`;`) to ensure that Datadog will properly handle the incoming payload.
+
+{{< see-also >}}
+
+See the [NGINX Controller Metrics]({{< relref "/controller/analytics/metrics/_index.md" >}}) docs for more information.
+
+{{< /see-also >}}
+
+## Verification
+
+Soon after you create the Datadog forwarder, you can view the selected metrics in Datadog.
+
+1. Log into the [Datadog web interface](https://app.datadoghq.com/).
+2. On the navigation menu, select **Metrics** > **Summary**.
+
+## What's Next
+
+- Refer to [Troubleshooting Forwaders]({{< relref "/controller/support/troubleshooting-forwarders.md" >}}) for tips on resolving common issues.
+
+{{< versions "3.8" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/forwarders/forward-analytics-to-otlp.md b/content/controller/analytics/forwarders/forward-analytics-to-otlp.md
new file mode 100644
index 000000000..d1aa43915
--- /dev/null
+++ b/content/controller/analytics/forwarders/forward-analytics-to-otlp.md
@@ -0,0 +1,67 @@
+---
+description: How to forward Analytics Metrics to OpenTelemetry Collector.
+docs: DOCS-532
+doctypes:
+- tutorial
+tags:
+- docs
+title: Forward Analytics Metrics to OpenTelemetry Collector
+toc: true
+weight: 201
+---
+
+## Overview
+
+Follow the steps in this guide to set up an F5 NGINX Controller integration that forwards metrics to OpenTelemetry Collector.
+
+## Before You Begin
+
+This guide assumes that you already have a working instance of any OpenTelemetry Collector.
+
+You will also need to [Create an Integration]({{< relref "/controller/platform/integrations/otlp-integration.md" >}}) for your OpenTelemetry Collector forwarder.
+
+## Create a Forwarder
+
+Take the following steps to create a forwarder for OpenTelemetry Collector:
+
+1. Open the NGINX Controller user interface and log in.
+2. Select the NGINX Controller menu icon, then select **Platform**.
+3. On the **Platform** menu, select **Data Forwarders**.
+4. On the **Data Forwarders** menu, select **Create Data Forwarder**.
+5. Add a name.
+6. (Optional) Add a display name.
+7. (Optional) Add a description.
+8. Select your **Integration Reference** from the dropdown list, or select **Create New** to create a new integration.
+9. In the **Collector Type** list, select `OTLP_HTTP` or `OTLP_GRPC`.
+10. In the **Source** list, select the type of data to forward: `METRICS`.
+11. In the **Output Format** list, select `OTLP`.
+12. The **Selector** field consists of the following query parameters (optional):
+
+- `names`: The list of metrics names that you want to forward.
+- `excluded_names`: The list of metric names that you don't want to forward.
+- `filter`: The conditions to use to refine the metrics data.
+- Example usage when selecting metrics: `"names=nginx.*&excluded_names=nginx.upstream.*&filter=app='myapp'"`
+
+13. (Optional) Select **Add Stream** to add additional streams, as needed.
+
+{{< important >}}
+
+Each metric is prefixed with a common namespace -- for example, "nginx-controller" -- before it's sent to OpenTelemetry Collector. This prefix is used only by OpenTelemetry Collector and is not applied to any internal NGINX Controller metrics. Refer to the [metrics catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) for the full list of valid metric names.
+
+We have tested compatability with OTLP collector v0.33.0. We will most likely support versions higher than this, assuming backwards compatability from OTLP.
+
+{{< /important >}}
+
+{{< see-also >}}
+
+See the [NGINX Controller Metrics]({{< relref "/controller/analytics/metrics/_index.md" >}}) docs for more information.
+
+{{< /see-also >}}
+
+## What's Next
+
+- Refer to [Troubleshooting Forwaders]({{< relref "/controller/support/troubleshooting-forwarders.md" >}}) for tips on resolving common issues.
+
+{{< versions "3.16" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/forwarders/forward-analytics-to-splunk.md b/content/controller/analytics/forwarders/forward-analytics-to-splunk.md
new file mode 100644
index 000000000..3c94a73e6
--- /dev/null
+++ b/content/controller/analytics/forwarders/forward-analytics-to-splunk.md
@@ -0,0 +1,68 @@
+---
+description: How to forward Analytics data to Splunk.
+docs: DOCS-533
+doctypes:
+- tutorial
+tags:
+- docs
+title: Forward Analytics Data to Splunk
+toc: true
+weight: 200
+---
+
+## Overview
+
+Follow the steps in this guide to set up an F5 NGINX Controller Integration that forwards data to [Splunk](https://www.splunk.com/).
+
+## Before You Begin
+
+This guide assumes that you are already an active Splunk user. If you haven't already done so, you will need to [install and configure Splunk](https://docs.splunk.com/Documentation) before you proceed.
+
+You will also need to [Create an Integration]({{< relref "/controller/platform/integrations/splunk-integration.md" >}}) for your Splunk forwarder.
+
+## Create a Forwarder
+
+Take the following steps to create a Forwarder for Splunk:
+
+1. Open the NGINX Controller user interface and log in.
+1. Select the NGINX Controller menu icon, then select **Platform**.
+1. On the **Platform** menu, select **Data Forwarders**.
+1. On the **Data Forwarders** menu, select the **Create Data Forwarder** quick action.
+1. Add a name.
+1. (Optional) Add a display name.
+1. (Optional) Add a description.
+1. Select your **Integration Reference** from the dropdown menu or select **Create New** to create a new Integration.
+1. In the **Collector Type** list, select `SPLUNK`.
+1. In the **Source** list, select the type of data to forward: `metrics` or `events`.
+1. In the **Output Format** list, select `SPLUNK`.
+1. The **Selector** field consists of the following query parameters (optional):
+
+ - `names` (inapplicable for `EVENTS`): The list of metrics names that you want to forward.
+ - `excluded_names` (inapplicable for `EVENTS`): The list of metric names that you don't want to forward.
+ - `filter`: The conditions to use to refine the metrics or events data.
+ - Example usage when selecting metrics: `"names=nginx.*&excluded_names=nginx.upstream.*filter=app='myapp'"`
+ - Example usage when selecting events: `"filter=type='security violation' AND app='my-app'"`
+
+1. (Optional) Add additional **Streams** as required using the **Add Stream** button.
+
+{{< important >}}
+
+Each metric will be prefixed with a common namespace -- such as `nginx-controller` -- before it is sent to Splunk. This prefix is used by Splunk only and is not applied to any of the internal NGINX Controller metrics. Refer to the [metrics catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) for the full list of valid metric names.
+
+In case of events, the "nginx-controller" namespace will be placed in the ["source" key](https://docs.splunk.com/Documentation/Splunk/8.1.1/Data/FormateventsforHTTPEventCollector#Event_metadata) and sent with each event.
+
+{{< /important >}}
+
+{{< see-also >}}
+
+See the [NGINX Controller Metrics]({{< relref "/controller/analytics/metrics/_index.md" >}}) docs for more information.
+
+{{< /see-also >}}
+
+## What's Next
+
+- Refer to [Troubleshooting Forwaders]({{< relref "/controller/support/troubleshooting-forwarders.md" >}}) for tips on resolving common issues.
+
+{{< versions "3.6" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/forwarders/forward-analytics-to-syslog.md b/content/controller/analytics/forwarders/forward-analytics-to-syslog.md
new file mode 100644
index 000000000..018a31c30
--- /dev/null
+++ b/content/controller/analytics/forwarders/forward-analytics-to-syslog.md
@@ -0,0 +1,53 @@
+---
+description: How to forward Analytics Events to Syslog.
+docs: DOCS-534
+doctypes:
+- tutorial
+tags:
+- docs
+title: Forward Analytics Events to Syslog
+toc: true
+weight: 201
+---
+
+## Overview
+
+Follow the steps in this guide to set up a F5 NGINX Controller Integration that forwards events to a syslog server.
+
+## Before You Begin
+
+This guide assumes that you already have a working instance of any syslog server.
+
+If you haven't already done so, you can use an open-source version of [Syslog-NG](https://www.syslog-ng.com/products/open-source-log-management/).
+
+You will also need to [Create an Integration]({{< relref "/controller/platform/integrations/syslog-integration.md" >}}) for your Syslog forwarder.
+
+## Create a Forwarder
+
+Take the following steps to create a Forwarder for Splunk:
+
+1. Open the NGINX Controller user interface and log in.
+1. Select the NGINX Controller menu icon, then select **Platform**.
+1. On the **Platform** menu, select **Data Forwarders**.
+1. On the **Data Forwarders** menu, select the **Create Data Forwarder** quick action.
+1. Add a name.
+1. (Optional) Add a display name.
+1. (Optional) Add a description.
+1. Select your **Integration Reference** from the dropdown menu or select **Create New** to create a new Integration.
+1. In the **Collector Type** list, select `SYSLOG`.
+1. In the **Source** list, select the type of data to forward: `events`. NGINX Controller can forward only `EVENTS` data to syslog.
+1. In the **Output Format** list, select `SYSLOG`.
+1. The **Selector** field consists of the following query parameters (optional):
+
+ - `filter`: The conditions to use to refine the metrics or events data.
+ - Example usage: `"filter=type='security violation' AND app='my-app'"`
+
+1. (Optional) Add additional **Streams** as required using the **Add Stream** button.
+
+## What's Next
+
+- Refer to [Troubleshooting Forwaders]({{< relref "/controller/support/troubleshooting-forwarders.md" >}}) for tips on resolving common issues.
+
+{{< versions "3.16" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/metrics/_index.md b/content/controller/analytics/metrics/_index.md
new file mode 100644
index 000000000..e5640c17d
--- /dev/null
+++ b/content/controller/analytics/metrics/_index.md
@@ -0,0 +1,10 @@
+---
+description: Learn about F5 NGINX Controller Metrics.
+menu:
+ docs:
+ parent: Analytics
+ weight: 50
+title: Metrics
+weight: 150
+url: /nginx-controller/analytics/metrics/
+---
diff --git a/content/controller/analytics/metrics/metrics-api.md b/content/controller/analytics/metrics/metrics-api.md
new file mode 100644
index 000000000..52b85d6ed
--- /dev/null
+++ b/content/controller/analytics/metrics/metrics-api.md
@@ -0,0 +1,481 @@
+---
+description: Tips and tricks for using the Metrics API query parameters to refine
+ your data.
+docs: DOCS-535
+doctypes:
+- tutorial
+tags:
+- docs
+title: Using the Metrics API
+toc: true
+weight: 50
+---
+
+## Overview
+
+You can use the F5 NGINX Controller Analytics module to monitor your NGINX instances and evaluate your applications' performance. The [Metrics API]({{< relref "/controller/api/_index.md" >}}) query parameters let you fine-tune your system data based on parameters such as time window, aggregation, time resolution, and filter.
+
+By using different combinations of these query parameters, you can gather information that lets you:
+
+- Identify which of your Apps receives the most traffic -- query for the highest number of requests among all apps.
+- Understand the behavior of your back-end server(s) -- query for upstream latency by instance or location.
+- Monitor your application performance -- filter on HTTP response codes to track the number of successful or failed requests by app and environment.
+- Understand how your App behavior and/or usage changes across version releases -- compare data like the examples above across different versions of your application.
+
+## Usage
+
+You can use the NGINX Controller [Metrics API]({{< relref "/controller/api/_index.md" >}}) to query for desired metric names and fine-tune the data returned based on the following parameters:
+
+- time window (`startTime` and `endTime`)
+- `filter`
+- `resolution`
+- `groupBy`
+- `seriesLimit`
+- `orderSeriesBy`
+- `dimensions`
+
+{{< note >}}
+Because NGINX Controller is constantly evolving, these example metrics and dimensions may differ from what you see with your NGINX Controller instance. Some metrics may require pre-configured applications to be visible in the API.
+{{< /note >}}
+
+### Understanding the Metrics API Response
+
+The [Metrics API]({{< relref "/controller/api/_index.md" >}}) response consists of query metadata and an array of `metrics` -- one array element for each queried metric.
+
+- The **metric** object includes the queried metric name and an array of data series associated with the metric.
+- The **series** object groups metrics data according to dimension values. The series consists of dimensions (key-value map), timestamps, and the timestamps' metric values.
+
+```json
+{
+ "metrics":[
+ {
+ "name":"http.request.count",
+ "series":[
+ {
+ "dimensions":{
+ "app":"app-name",
+ "component":"component-name",
+ "environment":"environment-name",
+ "gateway":"gateway-name",
+ "instance":"instance-name"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 1000
+ ]
+ },
+ {
+ "dimensions":{
+ "app":"app-name-2",
+ "component":"component-name",
+ "environment":"environment-name",
+ "gateway":"gateway-name",
+ "instance":"instance-name"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 2000
+ ]
+ }
+ ]
+ }
+ ],
+ "queryMetadata":{
+ "endTime":"2020-07-01T12:00:00.970106672Z"
+ }
+}
+```
+
+In the preceding example, there are two data series for the queried metric. The differentiator between the two series is the "app" name. This name is what makes NGINX metrics app-centric: you can easily distinguish metrics based on their dimensions' values, such as an App, Environment, or Gateway name.
+
+You can view the full list of the supported metrics and dimensions, with detailed descriptions, by querying the Catalog API:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/catalogs/metrics"
+```
+
+Likewise, you can get a full list of the available dimensions by querying the Catalogs API:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/catalogs/dimensions"
+```
+
+This information is also provided in the [Catalogs Reference]({{< relref "/controller/analytics/catalogs/_index.md" >}})).
+
+### Querying the Metrics API
+
+This section provides an overview of each query parameter and examples of using the parameters together to refine your data.
+
+The examples progress from basic usage to more advanced API queries.
+
+#### Names
+
+The `names` parameter is the only required parameter in the [Metrics API]({{< relref "/controller/api/_index.md" >}}).
+
+The following example query returns a response with the last recorded value for the queried metric: `http.request.count`:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count"
+```
+
+If the dimension values differ, the `series` array in the response will contain multiple items.
+
+It is possible to query the API for several metrics simultaneously. To do so, provide the metric names as a comma-separated list:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count,http.request.bytes_rcvd"
+```
+
+#### Time Window
+
+To get more than the last recorded value for the queried metric, use the following time window parameters:
+
+- `startTime` indicates the start of the time window to include metrics from (inclusive).
+- `endTime` means the end of the time window to include metrics from (non-inclusive).
+
+There are a few rules to remember when working with time window parameters:
+
+- If you provide an `endTime`, you must also provide a `startTime`;
+- `endTime` must be greater than `startTime`;
+- If you give a `startTime` but don't give an `endTime`, the `endTime` defaults to the current time.
+
+You can define time using the `ISO 8601` format or as an offset (for example, `2020-07-14T13:07:11Z`). An offset is a string that starts with `+` or `-`, followed by a number and a unit of time: `y`, `M`, `w`, `d`, `h`, `m`, or `s`. You can also use `now` to indicate the current timestamp.
+
+The following example request returns all the recorded metric values for the last three hours.
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count&startTime=now-3h"
+```
+
+The following example query contains a fully defined time window:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count&startTime=now-5h&endTime=2020-07-01T09:00:00Z"
+```
+
+In this case, the response contains metrics from 05:00:00 to 09:00:00 on the 1st of July 2020.
+
+#### Aggregations
+
+Using only `names` and time window parameters will give you the raw data points of metrics values.
+
+To get a more organized response, you can provide an aggregate function for each queried metric: `AVG`, `SUM`, `COUNT`, `MAX`, `MIN`, or `RATE`.
+
+{{< note >}}
+In the following definitions, `time period` refers to the `resolution` (if provided) or the difference between the `endTime` and `startTime` (when `resolution` is not provided).
+{{< /note >}}
+
+- `AVG` - calculates the average value of the metric data samples over the period
+- `SUM` - calculates the total value of the metric data samples over the period
+- `COUNT` - returns the number of collected data samples of the metric over the period
+- `MIN`/`MAX` - returns the minimal/maximal data sample of the metric from the given period
+- `RATE` - returns an average value of the metric calculated per second (always *per second*, regardless of the provided `resolution`), based on the data available in the given period
+
+{{< note >}}
+You must define a `startTime` when using aggregate functions.
+{{< /note >}}
+
+{{< see-also >}}
+The list of supported aggregate functions for any particular metric is available in the [Metrics Catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}})).
+{{< /see-also >}}
+
+For example, the following query returns a single value (per dimension set), which is the sum of the metric values for the last three hours. To get proper values, ensure that the `endTime` is greater than the `startTime`.
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&startTime=now-3h"
+```
+
+It is possible to use aggregated and non-aggregated metrics in a single query. For this query, the [Metrics API]({{< relref "/controller/api/_index.md" >}}) returns a single value per dimension set. That value is the sum of all of the metric's values for the last three hours.
+
+For example:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count),http.request.bytes_rcvd&startTime=now-3h"
+```
+
+{{< important >}}
+Using AVG aggregation with traffic metrics with the `.total` suffix may cause confusion because traffic metrics are already aggregated. To learn more, refer to the [Overview: Traffic Metrics]({{< relref "/controller/analytics/metrics/overview-traffic-metrics.md" >}})) topics.
+{{< /important >}}
+
+#### Resolution
+
+If you want to change the returned data's granularity, you can use `resolution` parameter. This parameter must be used in conjunction with an aggregation function and a time window (at least `startTime` must be provided).
+
+The `resolution` parameter must be a valid duration. The duration is a string that starts with a number, followed by a unit of time: `y`, `M`, `w`, `d`, `h`, `m`, or `s`.
+
+The following example query returns three aggregated metric values. Here, we're asking for the data from last three hours with one-hour granularity:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count),&startTime=now-3h&resolution=1h"
+```
+
+There may be situations when the returned resolution is lower than that requested in the query. This has to do with metrics retention periods—the older the metric, the lower the resolution.
+
+If the time window contains metrics with a lower resolution than was queried for, the API downsizes the granularity to the lowest possible value. You will see a warning in the `responseMetadata`:
+
+```json
+"responseMetadata": {
+ "warning": "Time window is above 8 days, Resolution is downsized to 300 seconds"
+}
+```
+
+If no `resolution` is provided, the maximum available resolution is returned. This is calculated as `endTime` - `startTime`.
+
+#### Filter
+
+This parameter, as the name indicates, filters results based on the value of dimensions. Filtering by dimension value can help to refine the data that's returned into a more specific set.
+
+The `filter` query consists of one or more predicates in the form of ``, where:
+
+- `` is the name of the dimension;
+- `` is one of the supported operators (`=`, `!=`, `<`, `<=`, `>=` `>`, `in` or `not`);
+- `` is value of the dimension(s) that you want to filter on.
+
+For example, the following query includes a simple filter on the app name. The query returns data for the application named `app1` for the last three hours.
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count&filter=app='app1'&startTime=now-3h"
+```
+
+{{< tip >}}
+
+- Predicates can be combined into logical expressions using `OR`, `AND`, and `(` `)`.
+- For matching values, wildcard (`*`) use is supported.
+- We recommend wrapping predicates in single quotes to ensure that the full query string is processed correctly.
+
+{{< /tip >}}
+
+The following example request uses `filter` with logical expressions:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=http.request.count&filter=app='ap*' and environment='prod'&startTime=now-3h"
+```
+
+#### GroupBy
+
+Using filters and aggregation functions may not be enough to allow you to get comprehensive information about a specific application or environment.
+
+The `groupBy` parameter helps to gather results according to the specified dimension(s). You can provide multiple dimension names as a comma-separated list.
+
+{{< note >}}
+
+- When using `groupBy`, you must use an aggregate function and a time window (`startTime` must be defined; `endTime` is optional).
+- If a request contains aggregated and non-aggregated metrics, the `groupBy` parameter will apply only to the aggregated metrics.
+
+{{< /note >}}
+
+For example, the following query returns data for any application with a name that starts with `ap` in the `prod` environment for the last three hours.
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&groupBy=app,alias&startTime=now-3h"
+```
+
+The API response for the query looks similar to the following:
+
+```json
+{
+ "metrics":[
+ {
+ "aggr": "SUM",
+ "name":"http.request.count",
+ "series":[
+ {
+ "dimensions":{
+ "app":"app-name",
+ "alias": "alias1"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 1000
+ ]
+ },
+ {
+ "dimensions":{
+ "app":"app-name-2",
+ "component":"alias1"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 2000
+ ]
+ }
+ ]
+ }
+ ],
+ "queryMetadata":{
+ "endTime":"2020-07-01T12:00:00.970106672Z"
+ }
+}
+```
+
+The API returns the data for the last three hours grouped by `app` and `alias` dimensions. Unlike other queries, the API only returns those dimensions that have been selected in `groupBy`. However, the series of different dimension values are still distinguished.
+
+#### SeriesLimit and OrderSeriesBy
+
+There are cases when you might want to view only a specific data series (for example, "Top-5"). To query the API for a particular series of data, you can define the `seriesLimit` and `orderSeriesBy` query parameters.
+
+- `seriesLimit` sets an upper limit on the number of series returned.
+- `orderSeriesBy` sorts the series values according to the order specified:
+
+ - Must consist of two tokens -- an aggregate function and a sort order. For example, `SUM DESC`, `MIN ASC`, and so on.
+ - Can be used only in combination with `seriesLimit`.
+
+When you specify a `seriesLimit`, the response always includes one other series with an `all` metric. This series aggregates the metric values of all the series that are not included in the result. If the total number of series returned is greater than the limit specified in the query parameter, an additional series named `other` is returned. This series aggregates the metrics values of the series outside of the specified limit.
+
+{{< note >}}
+When using `seriesLimit`, you can only specify one metric name in the `names` parameter and one `groupBy` parameter.
+{{< /note >}}
+
+**Example 1**
+The following example request uses `seriesLimit` to restrict the data returned to five series:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&groupBy=app&seriesLimit=5&startTime=now-3h&resolution=5m
+```
+
+The response contains data for the last three hours, grouped by the `app` and `alias` dimensions. Unlike the other example queries, in this example, the API returns just those dimensions that have been selected in `groupBy`. Each dimension and its corresponding values are provided as distinct items in a series.
+
+**Example 2**
+The following example query uses both `seriesLimit` and `orderSeriesBy`:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(some.metric.name)&groupBy=someDimension&seriesLimit=5&orderSeriesBy=MAX DESC&startTime=now-1d&endTime=now&resolution=5m
+```
+
+**Example 3**
+Building on the previous examples, here we use `seriesLimit` and `orderSeriesBy` to get the top-5 URIs with the highest number of bytes received for a specific App and Environment:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.bytes_rcvd)&startTime=now-1h&filter=app='app1' AND environment='qa'&groupBy=http.uri&seriesLimit=5&orderSeriesBy=MAX DESC
+```
+
+In this case, the API returns five data series for the last hour ordered by MAX value in descending order for bytes received per URL, where the data is related to the application `app1` deployed on the environment `prod`.
+
+Together, these parameters are particularly useful for refining data. The `seriesLimit` says how many series should be returned, `orderSeriesBy` parameter defines the criteria for ordering series.
+
+#### Dimensions
+
+You can use the `dimensions` query parameter to specify which dimension(s) should be included in each metric series' response.
+
+Dimensions not specified in the query parameter will not be included in the response. This may result in some series having the same dimension set but being returned as separate list items.
+
+The following example returns results for the specified metric, where `dimensions=environment`:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&dimensions=environment&startTime=now-3h
+```
+
+If you have multiple Apps, the response looks similar to the following example:
+
+```json
+{
+ "metrics":[
+ {
+ "aggr": "SUM",
+ "name":"http.request.count",
+ "series":[
+ {
+ "dimensions":{
+ "environment":"prod"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 1000
+ ]
+ },
+ {
+ "dimensions":{
+ "environment":"prod"
+ },
+ "timestamps":[
+ "2020-07-01T12:00:00Z"
+ ],
+ "values":[
+ 2000
+ ]
+ }
+ ]
+ }
+ ],
+ "queryMetadata":{
+ "endTime":"2020-07-01T12:00:00.970106672Z"
+ }
+}
+```
+
+If `dimensions` and `groupBy` parameters are both used, the list of provided `dimensions` must be a subset of the list provided in `groupBy`.
+
+The following example uses `dimensions` with `groupBy`:
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&groupBy=app,location&dimensions=app&startTime=now-3h&resolution=5m
+```
+
+The `dimensions` parameter also lets you omit the dimensions from the response altogether. To do so, define `dimensions` as an empty list (`dimensions=`).
+
+This results in several data series for the `http.request.count` metric without any dimensions being visible. That is not useful on its own; however, if you combine the empty `dimensions` parameter with metric aggregation, you will receive a single series with aggregated values.
+
+For example, the following example query sums all the values in all of the series of the `http.request.count` metric for the past three hours using the default `resolution`.
+
+```curl
+curl -X GET --cookie "session=" --url "{controller-IP}/api/v1/analytics/metrics?names=SUM(http.request.count)&startTime=now-3h&dimensions=
+```
+
+The response looks similar to the following example:
+
+```json
+{
+ "metrics":[
+ {
+ "aggr": "SUM",
+ "name":"http.request.count",
+ "series":[
+ {
+ "dimensions":{},
+ "timestamps":[
+ "2020-07-01T12:00:00Z",
+ "2020-07-01T12:00:30Z",
+ "2020-07-01T12:01:00Z",
+ "2020-07-01T12:01:30Z",
+ ...
+ ],
+ "values":[
+ 3000,
+ 2500,
+ 2800,
+ 1900,
+ ...
+ ]
+ }
+ ]
+ }
+ ],
+ "queryMetadata":{
+ "endTime":"2020-07-01T15:00:00Z"
+ }
+}
+```
+
+{{< important >}}
+You cannot use `dimensions` with the `seriesLimit` parameter.
+{{< /important >}}
+
+## What's Next
+
+- [Metrics Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}}))
+- [Dimensions Reference]({{< relref "/controller/analytics/catalogs/dimensions.md" >}}))
+- [Create Custom Dashboards]({{< relref "/controller/analytics/dashboards/custom-dashboards.md" >}}))
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/metrics/overview-metrics-metadata.md b/content/controller/analytics/metrics/overview-metrics-metadata.md
new file mode 100644
index 000000000..ff67020c8
--- /dev/null
+++ b/content/controller/analytics/metrics/overview-metrics-metadata.md
@@ -0,0 +1,81 @@
+---
+description: Understanding how the F5 NGINX Controller Agent collects and reports metrics
+ and metadata.
+docs: DOCS-536
+doctypes:
+- reference
+tags:
+- docs
+title: 'Overview: Metrics and Metadata'
+toc: true
+weight: 20
+---
+
+## Overview
+
+The data that F5 NGINX Controller collects can be divided into two categories:
+
+- **System metrics**: Data collected from the NGINX Plus API, the NGINX log files, and NGINX process state.
+- **Traffic metrics**: Data related to processed traffic, with the ability to distinguish the Application, API endpoint, or Environment that traffic is directed through.
+
+{{< note >}}
+The key difference between system and traffic metrics is that traffic metrics are pre-aggregated for each time period.
+{{< /note >}}
+
+Metrics are published at a regular interval of 60 or 30 seconds for system and traffic metrics, respectively.
+
+This topic gives an overview of the traffic metrics. Also known as "app-centric" metrics, traffic metrics contain information that lets you easily identify the App to which the data applies.
+
+{{< see-also >}}
+Refer to [View traffic metrics]({{< relref "/controller/analytics/metrics/view-traffic-metrics.md" >}}) for instructions on how to view traffic metrics using the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}}).
+{{< /see-also >}}
+## Metadata and Metrics That Are Reported
+
+The NGINX Controller Agent collects the following types of data:
+
+- **NGINX metrics.** The Agent collects NGINX-related metrics using the NGINX Plus API, and by monitoring the NGINX log files and NGINX process state.
+- **AVRD metrics.** AVRD sends app-centric data, so each metric has assigned dimensions like "application name" or "gateway". These metrics are related to processed traffic (for example, the number of bytes sent to a particular URL/endpoint).
+- **NGINX configuration.** After the initial installation, the NGINX configuration is uploaded to the NGINX Controller server. Configuration updates are also uploaded to the NGINX Controller server.
+- **System metrics.** These are key metrics describing the system. For example: CPU usage, memory usage, network traffic, etc.
+- **NGINX metadata.** These describe your NGINX instances, and include package data, build information, the path to the binary, build configuration options, and so on. NGINX metadata also includes the NGINX configuration elements.
+- **System metadata.** These are the basic information about the OS environment where the Agent runs. For example, the hostname, uptime, OS flavor, and other data.
+
+For the full list of metrics, see the [Metrics Catalog Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}})
+
+## Metrics Collection and Reporting Process
+
+The Agent mostly uses Golang's [gopsutil](https://github.com/shirou/gopsutil) to collect OS metrics.
+
+While the Agent is running on the host, it collects metrics at regular 20-second intervals. Metrics then are downsampled and sent to the Controller server once per minute. The Agent reports metadata to the NGINX Controller server every minute. Changes to the metadata can be examined using the Controller user interface.
+
+NGINX Controller stores historical metrics data in an analytics database. Metrics are aggregated and rolled-up as follows:
+
+- Data not older than 8 days are stored with best possible resolution (usually 1 min).
+- Data older than 8 days but not older than 30 days are stored with 5 min resolution.
+- Data older than 30 days but not older than 15 months are stored with 1 hour resolution.
+- Data older than 15 months are stored with 1 day resolution.
+
+### Parsing and Analyzing NGINX Configuration Files
+
+NGINX configuration updates are reported only when a configuration change is detected.
+
+The Agent checks the Controller server every 30 seconds for pending NGINX configuration changes. When changes are pending, the changes are applied and the NGINX is reloaded. Because the configuration is managed in the Controller server, the entire configuration is written to a single `nginx.conf` file.
+
+If the Agent cannot reach the Controller server to send the accumulated metrics, it continues to collect metrics and sends them to the Controller server as soon as connectivity is re-established. The maximum amount of data that can be buffered by the Agent is about 2 hour's worth of data.
+
+The Agent is able to automatically find all relevant NGINX configuration files, parse them, extract their logical structure, and send the associated JSON data to the Controller Server for further analysis and reporting.
+
+To parse SSL certificate metadata, the NGINX Controller Agent uses standard `openssl`(1) functions. SSL certificates are parsed and analyzed only when the corresponding [Agent settings]({{< relref "/controller/admin-guides/config-agent/configure-the-agent.md#default-agent-settings" >}}) are turned on. SSL certificate analysis is `off` by default.
+
+## Troubleshooting
+
+Most metrics are collected by the Agent without requiring the user to perform any additional setup. For troubleshooting instructions, see [Troubleshooting NGINX Controller Metrics]({{< relref "/controller/support/troubleshooting-controller.md" >}}).
+
+## What's Next
+
+- [Set up Metrics Collection]({{< relref "/controller/admin-guides/config-agent/configure-metrics-collection.md" >}})
+- [Metrics Reference]({{< relref "/controller/analytics/catalogs/metrics.md" >}})
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/metrics/overview-traffic-metrics.md b/content/controller/analytics/metrics/overview-traffic-metrics.md
new file mode 100644
index 000000000..de4b7271a
--- /dev/null
+++ b/content/controller/analytics/metrics/overview-traffic-metrics.md
@@ -0,0 +1,80 @@
+---
+description: Understanding how traffic metrics are collected, aggregated, and reported.
+docs: DOCS-537
+doctypes:
+- concept
+- reference
+tags:
+- docs
+title: 'Overview: Traffic Metrics'
+toc: true
+weight: 100
+---
+
+## Overview
+
+The data that F5 NGINX Controller collects can be divided into two categories:
+
+- **System metrics**: Data collected from the NGINX Plus API, the NGINX log files, and NGINX process state.
+- **Traffic metrics**: Data related to processed traffic, with the ability to distinguish the Application, API endpoint, or Environment that traffic is directed through.
+
+{{< note >}}
+The key difference between system and traffic metrics is that traffic metrics are pre-aggregated for each time period.
+{{< /note >}}
+
+Metrics are published at a regular interval of 60 or 30 seconds for system and traffic metrics, respectively.
+
+This topic gives an overview of the traffic metrics. Also known as "app-centric" metrics, traffic metrics contain information that lets you easily identify the App to which the data applies.
+
+{{< see-also >}}
+Refer to [View traffic metrics]({{< relref "/controller/analytics/metrics/view-traffic-metrics.md" >}}) for instructions on how to view traffic metrics using the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}}).
+{{< /see-also >}}
+
+## Available traffic metrics
+
+- `client.latency.{total | max | min | count}`
+- `client.network.latency.{total | max | min | count}`
+- `client.request.latency.{total | max | min | count}`
+- `client.ttfb.latency.{total | max | min | count}`
+- `client.response.latency.{total | max | min | count}`
+- `upstream.network.latency.{total | max | min | count}`
+- `upstream.header.latency.{total | max | min | count}`
+- `upstream.response.latency.{total | max | min | count}`
+- `http.request.bytes_rcvd`
+- `http.request.bytes_sent`
+- `http.request.count`
+
+{{< see-also >}}
+Refer to the [NGINX Controller Metrics Catalog]({{< relref "/controller/analytics/catalogs/metrics.md" >}}) for details about these and the other metrics that NGINX Controller reports.
+{{< /see-also>}}
+
+## Calculating traffic metrics
+
+As traffic flows through a configured application, NGINX Controller collects the traffic-related data. With heavy traffic, the number of single, distinguishable metrics can be challenging to discern. For this reason, the metric values are aggregated.
+
+The aggregation happens every publish period -- this period is stored in the `aggregation_duration` dimension, and is usually 30 seconds -- and is based on metric dimensions.
+
+Metrics are aggregated using four aggregation functions:
+
+- **SUM** for `http.request.bytes_rcvd`, `http.request.bytes_sent` and all metrics with `.total` suffix.
+- **MAX** for metrics with `.max` suffix.
+- **MIN** for metrics with `.min` suffix.
+- **COUNT** for metrics with `.count` suffix.
+
+### Example
+
+To better understand how metrics are aggregated, consider the following example:
+
+Imagine you have one application configured with one URI (recorded in the `http.uri` dimension of each traffic-related metric). In the last 30 seconds, a user queried that URI five times. The `client.request.latency` values for the requests were: 1 ms, 2 ms, 3 ms, 4 ms, and 5 ms.
+
+The final metric values returned by the Metrics API will be:
+
+- `http.request.count` = 5
+- `client.request.latency.total` = 15 ms
+- `client.request.latency.max` = 5 ms
+- `client.request.latency.min` = 1 ms
+- `client.request.latency.count` = 5
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/metrics/view-traffic-metrics.md b/content/controller/analytics/metrics/view-traffic-metrics.md
new file mode 100644
index 000000000..4afd3f773
--- /dev/null
+++ b/content/controller/analytics/metrics/view-traffic-metrics.md
@@ -0,0 +1,106 @@
+---
+description: How to view the traffic metrics gathered by NGINX Controller Analytics.
+docs: DOCS-538
+doctypes:
+- task
+- tutorial
+tags:
+- docs
+title: View Traffic Metrics
+toc: true
+weight: 150
+---
+
+## Overview
+
+This topic explains how to use the [NGINX Controller REST API]({{< relref "/controller/api/_index.md" >}})
+ to view traffic metrics.
+
+{{< see-also >}}
+Refer to [Overview: Traffic Metrics]({{< relref "/controller/analytics/metrics/overview-traffic-metrics.md" >}}) to learn how NGINX Controller collects, aggregates, and reports traffic metrics.
+{{< /see-also >}}
+
+## Before You Begin
+
+To view traffic metrics, first confirm that you've correctly configured NGINX Controller.
+
+The following resources should have the status `Configured`:
+
+- [Environment]({{< relref "/controller/services/manage-environments.md" >}})
+- [Gateway]({{< relref "/controller/services/manage-gateways.md" >}})
+- [App and Component]({{< relref "/controller/app-delivery/manage-apps.md" >}})
+
+Initially, the graphs will display `No data yet`, and querying the Metrics API for traffic metrics will result in an empty response. As soon as the Component starts to receive traffic, the traffic-related data will be displayed in the graphs and the [Dashboards]({{< relref "/controller/analytics/dashboards/overview-dashboard.md" >}}) in the NGINX Controller user interface and will be returned in API responses.
+
+{{< note >}}
+If traffic stops flowing to a resource (for example, an Application or Component), then no traffic metrics will be available for the resource.
+{{< /note >}}
+
+## View Traffic Metrics Using the REST API
+
+- To view the full list of metrics and dimensions, send a GET request to the `/analytics/catalogs/metrics` endpoint:
+
+ ```curl
+ curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/catalogs/metrics"
+ ```
+
+- To view a detailed description for a metric, send a GET request to the `/analytics/catalogs/metrics/{metricName}` endpoint:
+
+ ```curl
+ curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/catalogs/metrics/client.latency.total"
+ ```
+
+- Likewise, to view the full list of available dimensions, send a GET request to the `/analytics/catalogs/dimensions` endpoint:
+
+ ```curl
+ curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/catalogs/dimensions"
+ ```
+
+{{< see-also >}}
+Refer to the [Catalogs Reference]({{< relref "/controller/analytics/catalogs/_index.md" >}}) for information about all of the dimensions and metrics collected by NGINX Controller.
+{{< /see-also >}}
+
+## Example REST API Queries for Traffic Metrics
+
+Because traffic metrics are already aggregated, you should be careful about using the Metrics API for aggregations.
+
+### Example 1
+
+Goal: Retrieve the total number of requests for the last 3 hours:
+
+```curl
+curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/metrics?names=SUM(http.request.count)&startTime=now-3h"
+```
+
+The Metrics API returns a single value per dimension set. That value is the sum of the aggregated values (in 30s intervals) for the last 3 hours.
+
+### Example 2
+
+Goal: Retrieve an average value of max client latencies for my app -- let's call it `app1` -- for the last day:
+
+```curl
+curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/metrics?names=AVG(client.latency.max)&startTime=now-24h&filter=app='app1'"
+```
+
+### Example 3
+
+{{< important >}}
+Because traffic metrics are pre-aggregated, using AVG aggregation with these metrics isn't recommended.
+{{< /important >}}
+
+Imagine you have one application configured with one URI (recorded in the `http.uri` dimension of each traffic-related metric). In the last 30 seconds, a user queried that URI 5 times. The `client.request.latency` values for each request were: 1 ms, 2 ms, 3 ms, 4 ms, 5 ms.
+
+The final metric values returned by the Metrics API will be:
+
+- `client.request.latency.total` = 15 ms
+- `client.request.latency.count` = 5
+
+The following query returns the average `client.request.latency.total = 15`, as you have one aggregated sample with value 15.
+
+```curl
+curl -X GET --cookie "session=" --url "{Controller-FQDN}/api/v1/analytics/metrics?names=AVG(client.request.latency.total)&startTime=now-24h"
+```
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/analytics/view-app-security-analytics.md b/content/controller/analytics/view-app-security-analytics.md
new file mode 100644
index 000000000..d54262e27
--- /dev/null
+++ b/content/controller/analytics/view-app-security-analytics.md
@@ -0,0 +1,274 @@
+---
+description: How to view App Security Analytics.
+docs: DOCS-539
+doctypes:
+- concept
+- reference
+tags:
+- task
+title: View App Security Analytics
+toc: true
+weight: 500
+---
+
+## Overview
+
+When App Security flags or blocks a request made to an App Component as a security violation, it generates an App Security event.
+You can use the F5 NGINX Controller web interface or the REST API to view these events or their related statistics (measures). Metrics reflect the number of requests and bytes flagged or blocked. You can use the Security Violation Dimensions to help understand and interpret the analytics data.
+
+For descriptions of Security Metrics and Events Dimensions, refer to [About App Security]({{< relref "/controller/app-delivery/security/concepts/what-is-waf.md" >}}) page.
+
+## View App Security Analytics
+
+You can use the NGINX Controller user interface or the REST API to view App Security Analytics. You can use this data to get a quick, high-level understanding of how the App Security module processes requests to an App.
+
+1. Open the NGINX Controller user interface and log in.
+2. On the Navigation Bar, select **Services**.
+3. On the Services Menu, select **Apps**.
+4. On the Apps Overview page, select the App name link.
+5. Select **Security Analytics** under the Analytics sub-menu.
+
+## View Security Analytics for Components
+
+To view Security Analytics for individual Components, take the steps below.
+
+1. Open the NGINX Controller user interface and log in.
+2. On the Navigation Bar, select **Services**.
+3. On the Services Menu, select **Apps**.
+4. On the Apps Overview page, select the App name link.
+5. Select **Components** from the menu. Select the Component name link.
+6. Select **Security Analytics** under the Analytics sub-menu.
+
+### View App Security Events
+
+To view app security events:
+
+1. Open the NGINX Controller user interface and log in.
+2. On the Navigation Bar, select **Services**.
+3. On the Services Menu, select **Apps**.
+4. On the Apps Overview page, select the App name link.
+5. Select **Security Events** under the Analytics sub-menu.
+
+### View Security Events for Components
+
+To view the security events for components, take the following steps:
+
+1. Open the NGINX Controller user interface and log in.
+2. On the Navigation Bar, select **Services**.
+3. On the Services Menu, select **Apps**.
+4. On the Apps Overview page, select the App name link.
+5. Select **Components** from the sub-menu. Select the Component name link.
+6. Select **Security Events** under the Analytics sub-menu.
+
+## Example REST API Queries for App Security Metrics
+
+Requests which App Security has rejected or allowed:
+
+```curl
+https://{{host}}/api/v1/analytics/metrics?
+ startTime=0&
+ endTime=now&
+ names=sum(http.request.count)&
+ groupBy=request_outcome&
+ resolution=30m
+```
+
+Possible request outcomes are:
+
+- Passed: WAF allowed the request
+- Rejected: WAF blocked the request
+
+To get request counts based on how App Security processed the traffic:
+
+```curl
+https://{{host}}/api/v1/analytics/metrics?
+ startTime=0&
+ endTime=now&
+ resolution=5m&
+ names=sum(http.request.count)&
+ groupBy=request_outcome_reason&
+ filter=(
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+```
+
+| **request_outcome_reason values** | **Description** |
+|--------------------------------|-----------------|
+| \ | App Security did not process the traffic (in other words, App Security is not enabled). All events with this request_outcome_reason value should have a request_outcome `PASSED`.|
+| SECURITY_WAF_OK | App Security processed the traffic and no violations are found. All events with this request_outcome_reason value should have a request_outcome of `PASSED`.|
+| SECURITY_WAF_FLAGGED | App Security allowed the request, but it was flagged for review. All events with this request_outcome_reason value should have a request_outcome of `PASSED`.|
+| SECURITY_WAF_VIOLATION | App Security identified one or more violations and rejected the request. All events with this request_outcome_reason value should have a request_outcome of `REJECTED`.|
+
+If you feel App Security is blocking too many requests, you can turn on monitor-only mode.
+
+### Security Violation Events
+
+You can use Security Violation Events to investigate violations identified by App Security for requests made to an App Component. Follow the steps below to view the Security Events:
+
+1. Open the NGINX Controller user interface and log in.
+2. Select the NGINX Controller menu icon, then select **Analytics**.
+3. On the **Analytics Menu**, select **Component**.
+
+You can use the following example Events requests to collect App Security Analytics data by using the NGINX Controller REST API:
+
+- To view ‘security violation’ Events:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation')
+ ```
+
+- To get security violation details based on the Support ID seen on the request blocking page:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ waf.support_id='1880765231147185611')
+ ```
+
+- To get all events where WAF rejected to investigate:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ request_outcome='REJECTED')
+ ```
+
+- To get all events where WAF flagged to investigate:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ request_outcome_reason='SECURITY_WAF_FLAGGED')
+ ```
+
+- To get all events where WAF has rejected or flagged to review:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ request_outcome_reason in ('SECURITY_WAF_VIOLATION','SECURITY_WAF_FLAGGED'))
+ ```
+
+- To get all events where WAF has rejected or flagged for a specific App Component:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ request_outcome_reason in ('SECURITY_WAF_VIOLATION','SECURITY_WAF_FLAGGED') and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+ {{< tip >}}
+To get all Events, remove the Environment, App, and Component filters from the request call.
+ {{< /tip >}}
+
+- To find requests flagged by App Security’s violation rating algorithm as a possible or likely threat:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ request_outcome_reason = 'SECURITY_WAF_FLAGGED' and
+ waf.violation_rating in ('POSSIBLE_ATTACK','MOST_LIKELY_ATTACK') and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+ {{< important >}}
+This is important if you are using App Security WAF monitoring only mode. You can use it to understand the type of threats WAF believes should be blocked.
+ {{< /important >}}
+
+- To get Events that have triggered a specific signature-based violation by signature id:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ waf.signature_ids ='*200000098*' and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+ The substring search using wildcards or ‘IN’ operand should be used because each signature might be part of various combinations of signatures triggered by App Security per request.
+
+- To get Events that have triggered a specific a signature-based violation by signature id:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ waf.signature_names IN ('DIRECTORY_TRAVERSAL') and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+ The substring search using wildcards or ‘IN’ operand should be used because each signature might be part of various combinations of signatures triggered by App Security per request.
+
+- To get Events that triggered a particular attack type:
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ waf.attack_types='*Non-browser Client, Abuse of Functionality*' and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+ The substring search using wildcards or ‘IN’ operand should be used because each signature might be part of various combinations of attack types triggered by App Security per request.
+
+- To get Events from a remote address (client IP)
+
+ ```curl
+ GET https://{{host}}/api/v1/analytics/events?
+ startTime=0&
+ endTime=now&
+ filter=(
+ category='security violation' and
+ http.remote_addr='172.18.71.147' and
+ app='shopping' and
+ environment='prod' and
+ component='app-component')
+ ```
+
+## Related Pages
+
+- [About App Security]({{< relref "/controller/app-delivery/security/concepts/what-is-waf.md" >}})
+
+{{< versions "3.11" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/api-management/_index.md b/content/controller/api-management/_index.md
new file mode 100644
index 000000000..f8f0f8394
--- /dev/null
+++ b/content/controller/api-management/_index.md
@@ -0,0 +1,9 @@
+---
+description: Tasks for deploying and managing your APIs.
+menu:
+ docs:
+ parent: NGINX Controller
+title: API Management
+weight: 155
+url: /nginx-controller/api-management/
+---
diff --git a/content/controller/api-management/manage-apis.md b/content/controller/api-management/manage-apis.md
new file mode 100644
index 000000000..696158c9e
--- /dev/null
+++ b/content/controller/api-management/manage-apis.md
@@ -0,0 +1,507 @@
+---
+description: Use the F5 NGINX Controller API Manager to add APIs and control how your
+ APIs are exposed and consumed.
+docs: DOCS-569
+doctypes:
+- tutorial
+tags:
+- docs
+title: Manage Your APIs
+toc: true
+weight: 110
+---
+
+## Overview
+
+The F5 NGINX Controller API Management module provides full life cycle management for your APIs. This document provides a walkthrough of the steps needed to create, version, and publish your API using the NGINX Controller API Management module. When you have completed this guide, you should have the following resources:
+
+- An **API Definition**, which stores a collection of related API resources. It can be thought of as a folder.
+- An **API Version**, which describes a particular API and serves as the data contract. It describes available endpoints and operations on each endpoint and can also include API documentation.
+- A **Published API**, which represents an API Version that has been deployed to an NGINX Plus instance serving as an API Gateway.
+- (Optional) API documentation available via the Developer Portal.
+
+{{< note >}}
+
+- You must have an API Management module license installed to complete the steps in this guide.
+- The API Management module is available to users with the predefined [Admin or User Roles]({{< relref "/controller/platform/access-management/manage-roles.md#predefined-roles-and-role-groups" >}}).
+
+{{< /note >}}
+
+## Create an API Definition
+
+An API Definition functions as a collection of related API resources.
+
+1. Open the NGINX Controller user interface and log in.
+
+2. Select the NGINX Controller menu icon, then select **Services**.
+
+3. On the **Services** menu, select **APIs**.
+
+4. On the **All APIs** page, select **Create** and choose **API Definition**. Alternatively, you can also select **Create API Definition** from the Quick Actions list.
+
+## Create an API Version
+
+An API Version describes a particular API. It can be thought of as an API specification.
+
+1. Open the NGINX Controller user interface and log in.
+
+2. Select the NGINX Controller menu icon, then select **Services**.
+
+3. On the **Services** menu, select **APIs**.
+
+4. On the **All APIs** page, select **Create** and choose **API Version**. Alternatively, you can also select **Create API Version** from the Quick Actions list.
+
+5. Select an existing **API Definition** under which to group the API Version or select **Create New** to add a new **API Definition**.
+
+6. Choose how you would like to describe the API:
+
+ 1. [OpenAPI specification](#import-an-openapi-specification)
+
+ 2. [Configure manually](#define-api-resources-manually)
+
+ 3. [WSDL file](#import-a-web-services-description-language-wsdl-file) (Currently only supports unauthenticated, unencrypted traffic)
+
+7. Provide a version. If a version isn't provided, the default version `unspecified` is used.
+
+8. (Optional) Provide a display name.
+
+9. (Optional) Provide a description.
+
+ {{< note >}}
+
+ If your API specification includes a description, that text populates this field automatically when you [add your OpenAPI spec](#import-an-openapi-specification).
+
+ {{< /note >}}
+
+10. (Optional) Add tags.
+
+### Import an OpenAPI Specification
+
+The APIM module supports import of a valid OpenAPI v3 specification formatted as valid JSON or YAML.
+
+{{< note >}}
+
+If your API spec includes documentation elements, the "Enable documentation" option is selected automatically. You do not need to take any additional steps to document your API.
+
+{{< /note >}}
+
+**To import your spec by uploading a file:**
+
+1. Select **OpenAPI Specification**.
+
+2. Select **Import file**.
+
+3. Drag and drop your file into the upload box, or select **Browse** to find and upload a file.
+
+**To import your spec by copying and pasting:**
+
+1. Select **OpenAPI Specification**.
+
+2. Select **Copy and paste specification text**.
+
+3. Paste or type your API in the space provided.
+
+Once you have imported your API spec, select **Next** to continue to the **Resources** page.
+
+### Define API Resources Manually
+
+Take the steps below to manually add your API resources.
+
+1. Select **Configure Manually**.
+
+2. Select **Next** to continue to the **Resources** page.
+
+3. Select **Add API Resource**.
+
+4. Select the **Match Type** to use for the API resource path.
+
+5. Specify the **Path** for the API resource.
+**Tip**: Path should start with `/`, for example, `/userlookup/{userid}/attributes/{surname}`.
+
+6. Select the HTTP method(s).
+
+7. (Optional) [Document Your API](#document-your-api).
+
+8. Review the API spec that will be submitted to create the **API Version**.
+
+9. Select **Submit** to save the **API Version**.
+
+### Document Your API
+
+Follow the steps below to document your API.
+
+{{< note >}}
+
+API documentation must follow the OpenAPI 2.0/3.0 Specification.
+
+If you uploaded an API spec that contains documentation, you don't need take any further steps to document your API.
+
+{{< /note >}}
+
+{{< tip >}}
+
+Skip to step 6 if you're continuing from the [Define API Resources Manually](#define-api-resources-manually) section.
+
+{{< /tip >}}
+
+1. Open the NGINX Controller user interface and log in.
+
+2. Select the NGINX Controller menu icon, then select **Services**.
+
+3. On the **Services** menu, select **APIs**.
+
+4. On the **All APIs** page, select the **API Version** for which you want to create documentation. Click the pencil (edit) button to edit the API Version.
+
+5. Select **Resources**.
+
+6. Select the pencil (edit) icon next to the method or methods that you want to document.
+
+7. Select **Enable Documentation**.
+
+8. Add a summary.
+
+9. (Optional) Add a description.
+
+10. (Optional) Add a request body description.
+
+11. (Optional) Add a sample request.
+
+12. Specify whether the request body is required.
+
+13. To add a parameter, select **Add Parameter**.
+
+14. Provide the parameter name.
+
+15. (Optional) Provide a parameter description.
+
+16. Select the parameter type.
+
+17. Select the parameter value.
+
+18. (Optional) Specify whether the parameter is required.
+
+19. To add a response, select **Add Response**.
+
+20. Provide the HTTP Response status code.
+
+21. Provide a description.
+
+22. (Optional) Provide a sample response in JSON format.
+
+23. Select **Next** to review the API spec that will be submitted to update the **API Version**.
+
+24. Select **Submit** to save the **API Version**.
+
+### Import a Web Services Description Language (WSDL) file
+
+ {{< caution >}}
+
+Currently, only HTTP is supported for SOAP-REST proxy traffic. Traffic will be unauthenticated and unencrypted, and as a result will be vulnerable to several security risks. It should be treated as a beta/preview feature.
+
+ {{< /caution >}}
+
+The APIM module supports importing a WSDL file that describes a SOAP service.
+
+**To import your spec by uploading a file:**
+
+1. Select **WSDL File**.
+
+2. Select **Import file**.
+
+3. Drag and drop your file into the upload box, or select **Browse** to find and upload a file.
+
+**To import your spec by copying and pasting:**
+
+1. Select **WSDL file**.
+
+2. Select **Copy and paste WSDL text**.
+
+3. Paste or type your API in the space provided.
+
+Once you've imported your API spec, select **Next** to continue to the **Resources** page. Note that you need to submit the API spec before you can modify the **Resources** and **Schema**. Select **Submit** to save the **API Version.**
+
+### Modify Schema and Resources for an API Version created from a WSDL file
+
+Take the following steps to **Edit** add your API Version:
+
+1. On the **All APIs** page, select the **API Version** that was created from a WSDL
+
+2. Select **Next** to continue to the **Resources** page.
+
+3. For each **SOAP operation**, choose the appropriate equivalent **REST Method**.
+
+4. (optional) Modify the **Path** for the API resource as desired.
+
+ {{< tip >}}
+
+ Path should start with `/`, for example, `/userlookup/{userid}/attributes/{surname}`.
+
+ {{< /tip >}}
+
+5. Select **Next** to continue to the **Schema** page
+
+6. (Optional) For each JSON schema, modify the **Property** as desired
+
+7. Review the API spec that will be submitted to create the **API Version**.
+
+8. Select **Submit** to save the **API Version**.
+
+## Publish an API
+
+You need at least one of each of the resources listed below to complete this section. If you haven't already created the required resources, you can do so while configuring the Published API.
+
+- [Environment]({{< relref "/controller/services/manage-environments.md" >}})
+
+- [Gateway]({{< relref "/controller/services/manage-gateways.md" >}})
+
+- [App]({{< relref "/controller/app-delivery/manage-apps.md" >}})
+
+- [Identity Provider]({{< relref "/controller/services/manage-identity-providers.md" >}})
+
+ (required to add Authentication to the Published API Component).
+
+{{< tip >}}
+You can connect one or more [Developer Portals]({{< relref "/controller/api-management/manage-dev-portals.md" >}}) to your Published API to host your API documentation. This can be done either when creating or editing your Published API, or independently via the API Quick Actions menu.
+{{< /tip >}}
+
+### Add a Published API
+
+1. Open the NGINX Controller user interface and log in.
+
+2. Select the NGINX Controller menu icon, then select **Services**.
+
+3. On the **Services** menu, select **APIs**.
+
+4. On the **All APIs** page, select the **API Version** that you want to publish.
+
+5. Select **Add Published API**.
+
+#### Configure the Published API
+
+On the **Create Published API** *Configuration* page:
+
+1. Select the **API Definition Version** that you want to publish.
+
+2. (Optional) Provide a **Base Path** for the Published API.
+
+3. Specify whether the **Strip Base Path** parameter is required.
+
+ {{< note >}}
+
+ The `Strip Base Path` option modifies the path that is passed from the Gateway to the upstream host. When the option is selected, the base path will be removed from the original request when the request is passed to the upstream host. If the option is not selected, the original request -- including the base path -- is passed from the Gateway to the upstream host.
+
+ {{< /note >}}
+
+4. Provide a Name and/or Display Name for the Published API.
+
+5. (Optional) Provide a description for the Published API.
+
+6. (Optional) Add tags.
+
+7. Select **Next**.
+
+#### Define the Published API Deployment
+
+For each of the steps below, you can create a new resource for the Published API by selecting the **Create New** link.
+
+On the **Create Published API** *Deployment* page:
+
+1. Select the **Environment** that the Published API belongs to.
+
+2. Select the **App** that the Published API represents.
+
+3. Select the **Gateway(s)** that will expose the Published API.
+
+4. Select the **Dev Portal(s)** that will host documentation for the Published API.
+
+5. Select **Next**.
+
+#### Define the Routing Rules
+
+On the **Create Published API** *Routing* page:
+
+1. Select the **Add New** link to create a new App Component resource for the Published API. The **Create App Component** page has multiple sections.
+
+2. On the **Create App Component** *Configuration* page:
+
+ 1. Provide the name for your Component.
+
+ 2. (Optional) Provide a Display Name.
+
+ 3. (Optional) Provide a Description.
+
+ 4. (Optional) Add any desired tags.
+
+ 5. (Optional) Select the error response format.
+
+ 6. Select **Next**.
+
+3. On the **Create App Component** *Workload Groups* page:
+
+ 1. Provide a Workload Group Name.
+
+ 2. (Optional) Select a Location. The default Location is 'Unspecified'. This value is applied automatically to "bring your own" (BYO) NGINX Plus instances that were not deployed by NGINX Controller.
+
+ 3. Define the backend workload URIs.
+
+ 4. (Optional) Define the DNS Server.
+
+ 5. (Optional) Select the Load Balancing Method. The default value is `Round Robin`.
+
+ 6. (Optional) Select the Session Persistence Type (applicable only to Web Components).
+
+ 7. (Optional) Select the Desired Proxy Settings (applicable only to Web Components).
+
+ 8. Select **Next**.
+ {{< see-also >}}
+
+ - Refer to the [Manage Locations]({{< relref "/controller/infrastructure/locations/manage-locations.md" >}}) topic for more information.
+
+ - Refer to the [NGINX Plus Admin Guide](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/) for more information about the available options.
+
+ {{< /see-also >}}
+ {{< tip >}}
+ Hover your pointer over the info icon for each setting to learn about the expected values and requirements.
+ {{< /tip >}}
+
+
+4. On the **Create App Component** *Rate Limiting* page:
+
+ 1. Enable Rate Limiting and select a **Key**.
+
+ 2. Select options for Rate and Units.
+
+ 3. (Optional) Select options for Excess Request Processing and Ignore Initial N Requests.
+
+ 4. Select options for Reject Status Code.
+
+ 5. Select **Next**.
+
+5. On the **Create App Component** *Authentication* page:
+
+ 1. Select **Add Authentication**.
+
+ 2. Select an [**Identity Provider**]({{< relref "/controller/services/manage-identity-providers.md" >}}).
+
+ 3. Select a **Credential Location**.
+
+ 1. (Optional) Enable [**Conditional Access**]({{< relref "/controller/services/available-policies.md#conditional-access" >}}).
+
+ 4. Select **Next**.
+
+{{< important >}}
+
+The **Advanced Security** features require an *NGINX Controller API Management Advanced Security* license.
+
+{{< /important >}}
+
+6. On the **Create App Components** *Advanced Security* page:
+
+ 1. (Optional) Select **Enable Web Application Firewall (WAF)** to monitor and block suspicious requests or attacks.
+
+ 2. (Optional) Select **Monitor Only** to allow traffic to pass without being rejected. Security events are still generated and metrics are still collected. Refer to [About App Security Analytics]({{< relref "/controller/analytics/view-app-security-analytics.md" >}}) for more information.
+
+ 3. (Optional) Add the signature(s) that you want WAF to ignore. You can specify multiple signatures as a comma-separated list.
+
+ 4. Select **Next**
+
+ {{< see-also >}} Refer to the [Default WAF Policy]({{< relref "/controller/app-delivery/security/concepts/app-sec-default-policy-original.md" >}}) topics to learn more about the default protection provided by NGINX App Protect. {{< /see-also >}}
+
+
+7. On the **Create App Component** *Ingress* page:
+
+ 1. (Optional) Set the desired **Client Max Body Size**.
+ 2. Select **Next**.
+
+ {{< see-also >}}
+
+ Refer to the [NGINX module docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size) for more information about this option.
+
+ {{< /see-also >}}
+
+
+8. On the **Create App Component** *Monitoring* page:
+
+ 1. (Optional) Enable **Health Monitoring** and define the desired Monitoring Request and Response. Health Monitoring is disabled by default.
+
+ 2. (Optional) Specify the URI to use in health check requests (applicable only to Web Components). The default is `/`. For TCP/UDP Components, specify the Send string.
+
+ 3. (Optional) Specify the port to use when connecting to a server to perform a health check. The server port is used by default.
+
+ 4. (Optional) Set the interval to wait between two consecutive health checks. The default is 5 seconds.
+
+ 5. (Optional) Specify the number of consecutive passed health checks that must occur for a server to be considered healthy. The default is `1`.
+
+ 6. (Optional) Specify the number of consecutive failed health checks that must occur for a server to be considered unhealthy. The default is `1`.
+
+ 7. (Optional) Specify the default state for the server. The default state is `HEALTHY`.
+
+ 8. (Optional) Specify the starting HTTP status code to match against (applicable only to Web components).
+
+ 9. (Optional) Specify the ending HTTP status code to match against (applicable only to Web components).
+
+ 10. (Optional) Select whether a response should pass in order for the health check to pass (applicable only to Web components). By default, the response should have status code `2xx` or `3xx`.
+
+ 11. Select **Next**.
+
+ {{< see-also >}}
+
+ Refer to the [NGINX module docs](http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check) for more information about these options.
+
+ {{< /see-also >}}
+
+9. On the **Create App Component** *Logs* page:
+
+ 1. (Optional) Select the logs to enable:
+
+ § Error Log
+
+ § Access Log
+
+ 2. (Optional) Specify the log format to use.
+
+ 3. Select **Next**.
+
+ {{< see-also >}}
+
+ Refer to the [NGINX docs](http://nginx.org/en/docs/http/ngx_http_log_module.html) for more information about these options.
+
+ {{< /see-also >}}
+
+9. On the **Create App Component** *Programmability* page:
+
+ The following settings are applicable **only to Web components**.
+
+ 1. (Optional) Select **Add URI Redirects** and define the desired redirect condition(s).
+
+ 2. (Optional) Select **Add URI Rewrite** and define the desired rewrite pattern(s).
+
+ 3. (Optional) Select **Add Request Header Modification** and define how to modify the request header.
+
+ 4. (Optional) Select **Add Response Header Modification** and define how to modify the response header.
+
+ 5. Select **Next**.
+
+ {{< see-also >}}
+
+ Refer to the [NGINX module docs](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) for more information about these options.
+
+ {{< /see-also >}}
+
+ 6. Select **Next** to review the API spec that will be sent to create the App Component.
+
+ 7. Drag and drop resources one at a time, or move multiple resources by selecting the checkboxes next to the desired resources, from the **Unrouted** column to the desired Component in the **Components** list. You can use the search bar to narrow down the list.
+ **Note:** Resources can be dragged between **Components** and back to the **Unrouted** section either one at a time or by multi-select.
+
+ 8. Select **Next** to review the API spec that will be sent to create the Published API.
+
+ 9. Select **Submit** to create the Published API.
+
+## Create a Developer Portal
+
+Once you have created an API Definition and a Published API, you can host your API in a Developer Portal.
+
+From the **API Definitions** page, select **Create Dev Portal** from the Quick Actions menu. Then, follow the steps in [Create a Developer Portal]({{< relref "/controller/api-management/manage-dev-portals.md" >}}) to create, customize, and publish your Dev Portal.
+
+{{< versions "3.0" "3.18" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
diff --git a/content/controller/api-management/manage-dev-portals.md b/content/controller/api-management/manage-dev-portals.md
new file mode 100644
index 000000000..02923d76e
--- /dev/null
+++ b/content/controller/api-management/manage-dev-portals.md
@@ -0,0 +1,140 @@
+---
+description: Learn how to create and manage Developer Portals for your API documentation.
+docs: DOCS-570
+doctypes:
+- tutorial
+tags:
+- docs
+title: Manage Developer Portals
+toc: true
+weight: 120
+---
+
+## Overview
+
+You can use F5 NGINX Controller Developer Portals (also called 'Dev Portals') to create and manage beautiful, easy-to-use API reference documentation to support your [Published APIs]({{< relref "/controller/api-management/manage-apis.md#publish-an-api" >}}).
+
+## About Developer Portals
+
+In NGINX Controller, each Dev Portal sits within an Environment. An Environment can contain multiple Dev Portals. You can use the same Dev Portal names across different Environments, which means you can create "test", "dev", and "production" versions of your Dev Portal across the corresponding Environments.
+
+Each Dev Portal is associated with a Gateway, which defines the URI at which users can access the Dev Portal -- for example, `developer.acme.com`. A Gateway for a Developer Portal can be placed on a dedicated Instance, or share an Instance with other Gateway resources.
+
+## Before You Begin
+
+You must complete the steps below before you can create a Developer Portal.
+
+1. [Create an Environment]({{< relref "/controller/services/manage-environments.md" >}}).
+1. [Create a Gateway]({{< relref "/controller/services/manage-gateways.md" >}}) for the Dev Portal.
+
+ {{< tip >}}
+You can create multiple Dev Portal Gateways on the same Instance. If you do so, be sure to use a unique hostname and port for each. For example:
+
+- Gateway 1's ingress URI is `https://dev-developer.acme.com`.
+- Gateway 2's ingress URI is `https://test-developer.acme.com`. These resources might both have IP addresses and ports that are accessible only from within your private network.
+- Gateway 3's ingress URI is `https://developer.acme.com`. This resource would have a public IP address and be accessible via the internet.
+
+If you create multiple Dev Portal Gateways on the same Instance using the same hostname and port, the Dev Portal configuration will fail.
+ {{< /tip >}}
+
+1. [Create an API Definition]({{< relref "/controller/api-management/manage-apis.md#create-an-api-definition" >}}).
+
+ {{< tip >}}
+If you choose to [define your API manually]({{< relref "/controller/api-management/manage-apis.md#define-resources-manually" >}}), be sure to [document your API]({{< relref "/controller/api-management/manage-apis.md#document-your-api" >}}).
+ {{< /tip >}}
+
+1. [Create a Published API]({{< relref "/controller/api-management/manage-apis.md#publish-an-api" >}}).
+
+ {{< important >}}
+You must create an App Component when creating a Published API. You'll [assign routes]({{< relref "/controller/api-management/manage-apis.md#define-the-routing-rules" >}}) from the API Definition to this Component.
+
+Both the Published API and the associated App Component must be successfully created before you can create a Dev Portal.
+
+See [Manage Your APIs]({{< relref "/controller/api-management/manage-apis.md" >}}) and the [troubleshooting](#troubleshoot-dev-portal-publication) section below for more information.
+
+You also have the option to associate Dev Portal(s) in the *Deployment* page when you [Add a Published API]({{< relref "/controller/api-management/manage-apis.md#add-a-published-api" >}}). If you already have a Published API and you want to create a new Dev Portal to host it, complete the tasks described in this guide.
+
+ {{< /important >}}
+
+## Create a Developer Portal
+
+To create a Dev Portal, take the steps below:
+
+1. Open the NGINX Controller user interface and log in.
+2. Select the NGINX Controller menu icon, then select Services.
+3. On the **Services** menu, select APIs.
+4. On the APIs page, select **Create Dev Portal** from the Quick Actions menu.
+
+ {{< tip >}}
+If you want to connect one or more Dev Portals to an existing Published API, you should select the **Edit Published API** option. The API Documentation will be published to the selected Dev Portal(s). Refer to the [Define the Published API Deployment]({{< relref "/controller/api-management/manage-apis.md#define-the-published-api-deployment" >}}) section for more information and instructions.
+ {{< /tip >}}
+
+### Configure the Developer Portal
+
+On the **Create Dev Portal** *Configuration* page:
+
+1. Provide a resource name for the Dev Portal.
+2. (Optional) Provide a display name, description, and tags.
+3. Select the desired Environment, or select Create to create a new resource.
+4. Select a Gateway, or select Create to create a new resource.
+5. Select the Published API(s) that you want to host in the Dev Portal.
+6. Select **Next** to move to the **Themes** page.
+
+### Define the Dev Portal Theme
+
+On the **Create Dev Portal** *Themes* page:
+
+1. Select **Brand** to define the following elements:
+
+ - **Brand Name**,
+ - **Logo**, and
+ - **Favicon**
+
+2. Select **Next**.
+3. Set the **Colors** for theme elements. Then, select **Next**.
+4. Set the **Fonts** for the theme. Then, select **Next**.
+5. Review the **API Spec**, then select **Submit**.
+
+> You should now be able to access the Dev Portal via the hostname and port that you assigned to the Dev Portal Gateway.
+
+## View, Edit, or Delete a Developer Portal
+
+To view, edit, or delete a Dev Portal, take the steps below:
+
+1. Open the NGINX Controller user interface and log in.
+2. Select the NGINX Controller menu icon, then select Services.
+3. On the **Services** menu, select APIs.
+4. On the APIs menu, select **Dev Portals**.
+
+To **edit** a Dev Portal:
+
+1. Select the **Edit** icon for the Dev Portal.
+2. Edit the Dev Portal as desired.
+
+ - Select **Configure** to update the Dev Portal configurations, including the Environment, Gateway, and Published API.
+ - Select **Brand** to customize the **Brand Name** and to upload a **Logo** and **Favicon**.
+ - Select **Color** to customize the Dev Portal theme colors.
+ - Select **Fonts** to customize the Dev Portal theme fonts.
+
+3. Select **Submit** to save your changes.
+
+To **delete** a Dev Portal, select the **Delete** icon. Then, select **Delete** in the confirmation prompt window.
+
+## Troubleshoot Dev Portal Publication
+
+If the Gateway that the Dev Portal is associated with is in an error state, publishing your Dev Portal will fail. You won't necessarily see an error in the Dev Portals section of the user interface when this happens, but configuration errors in these resources will impact Dev Portal functionality.
+
+- App Component configuration errors are displayed only in the App Component section of the user interface.
+- Published API configuration errors are displayed in the Published APIs section of the user interface, as well as in the Dev Portal.
+- Dev Portal configuration errors are not displayed in the NGINX Controller user interface.
+
+If your Dev Portal failed to publish, check the status of the Gateway first; resolve any issues with the Gateway, then try publishing the Dev Portal again.
+If the issue persists, check the other resources for configuration errors.
+
+## What's Next
+
+- [Learn about Policies]({{< relref "available-policies.md" >}})
+- [Manage Your APIs]({{< relref "manage-apis.md" >}})
+
+{{< versions "3.7" "3.18" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
diff --git a/content/controller/api/_index.md b/content/controller/api/_index.md
new file mode 100644
index 000000000..fbce5140c
--- /dev/null
+++ b/content/controller/api/_index.md
@@ -0,0 +1,9 @@
+---
+description: Learn how to use the F5 NGINX Controller REST API.
+menu:
+ docs:
+ parent: NGINX Controller
+title: API Reference
+weight: 210
+url: /nginx-controller/api/reference/
+---
diff --git a/content/controller/api/overview.md b/content/controller/api/overview.md
new file mode 100644
index 000000000..58455c2ff
--- /dev/null
+++ b/content/controller/api/overview.md
@@ -0,0 +1,124 @@
+---
+description: Provides information about the F5 NGINX Controller API.
+docs: DOCS-343
+doctypes:
+- concept
+layout: docs
+tags:
+- docs
+title: API Overview
+toc: true
+weight: 10
+---
+
+## Introduction
+
+The F5 NGINX Controller API is a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) API that allows you to programmatically manage your NGINX Plus data planes.
+
+NGINX Controller follows an "API-first" approach, which means that all NGINX Controller functionality is exclusively exposed through declarative and resource-oriented APIs. Even the user interface (user interface) uses our REST API! You'll find examples of REST request bodies in the user interface. You can rest assured that the example you see is correct, because that is the call that the user interface is going to make to apply your requested configuration.
+
+## Encoding
+
+All NGINX Controller API endpoints expect and return JSON-formatted data by default.
+When appropriate, the API accepts and returns other media types, such as file uploads or downloads.
+
+All JSON-formatted data is expected to be encoded using UTF-8 as described by the [IETF JSON Spec](https://tools.ietf.org/html/rfc8259).
+If you do not specify a specific media type in an API call, then the API defaults to `"application/json"`. If you specify multiple acceptable media types, the first type that the API supports is chosen for the response. In the event of a request for a media type that the API doesn't support, it returns a "415 Unsupported Media Type" response.
+
+## Object Model
+
+The NGINX Controller API -- as well as the user interface and the product documentation -- is organized into four top-level areas:
+
+- **Analytics**: Enables data visualization for NGINX Controller.
+- **Infrastructure**: Lets you manage your NGINX Plus instances and certain aspects of the host machines on which NGINX Controller and NGINX Plus instances run.
+- **Platform**: Lets you manage NGINX Controller options and configurations, including Users, Roles, Licenses, and Global Settings.
+- **Services**: Lets you manage your applications and APIs.
+
+The diagrams below demonstrate how the different objects at the Service level relate to each other:
+
+1. All Service objects are part of an Environment.
+1. Gateways and Certs can be defined at the Environment level --or-- at the Component Level. The diagram below shows an example of how traffic flows through a Gateway to an App.
+1. Components are child objects that represent the back-end server(s) that host your App or API.
+ {{}}A Component can represent an application **or** an API. The same Component cannot be used for both App Delivery and API Management.{{}}
+1. Certs can be added to a Gateway or to an individual Component.
+
+{{< img src="/ctlr/img/services-object-model-example.png" alt="Diagram showing the relationship of objects in an Environment within the Services area." >}}
+{{< img src="/ctlr/img/traffic-flow-example-1.png" alt="Example traffic flow through a gateway to app components that represent a back-end application. Certs can be configured at the gateway or at the app component level." >}}
+
+### Permissions
+
+Access to each of these areas is determined by your User Role. Roles grant Users access to specific Environments; Role permission levels define what content you can see ("Read" access) and interact with ("Write" access). Users with Roles that contain "Full" access can interact with all areas.
+
+The diagram below shows a sample System Administrator (or, "SysAdmin") workflow. The SysAdmin user has full administrator permissions, which allows creation of objects in all areas. In this workflow, the SysAdmin user creates an Environment; then creates a Role that has permission to interact with objects in that Environment; and, finally, creates a User. The Role grants the User access to objects in the Environment.
+
+{{< img src="/ctlr/img/netops-workflow.png" alt="Example System Admin workflow" >}}
+
+The diagram below shows a sample deployment workflow. In this workflow, the user - a Deployment Manager - has read and write access to objects in one specific Environment, but no access to other Environments. Within the allowed Environment, the user can create objects or select from objects that were added by a system administrator. In this workflow, the Deployment Manager creates an App and an App Component. Associated objects like Certs and Gateways can be added -- or selected from a list -- when adding the App Component. The configs for load balancing, monitoring, and URI redirects are defined as part of the App Component as well.
+
+{{< img src="/ctlr/img/devops-workflow-simple.png" alt="Example deployment workflow" >}}
+
+{{< see-also >}}
+
+- [Managing Roles & Users]({{< relref "/controller/platform/access-management/manage-users.md" >}})
+
+{{< /see-also >}}
+
+## Authentication
+
+The NGINX Controller API uses session cookies to authenticate requests. The session cookie is returned in response to a `GET /api/v1/platform/login` request. See the Login endpoint in the [NGINX Controller API Reference]({{< relref "/controller/api/_index.md" >}}) documentation for information about session cookie timeouts and invalidation.
+
+{{< tip >}}
+You can send a GET request to the login endpoint to find the status of the session token.
+{{< /tip >}}
+
+For example:
+
+- Login and capture the session cookie:
+
+ ```curl
+ curl -c cookie.txt -X POST --url 'https://198.51.100.10/api/v1/platform/login' --header 'Content-Type: application/json' --data '{"credentials": {"type": "BASIC","username": "arthur@arthurdent.net","password": "Towel$123"}}'
+ ```
+
+- Use the session cookie to authenticate and get the session status:
+
+ ```curl
+ curl -b cookie.txt -c cookie.txt -X GET --url 'https://198.51.100.10/api/v1/platform/login'
+ ```
+
+
+## Resource Types
+
+The NGINX Controller API contains two types of resources: immediately consistent and eventually consistent.
+
+Immediately consistent resources are synchronous. For these resources, any changes you make will be applied at the time the request is received. Requests to modify state using an API write operation (POST, PUT, PATCH or DELETE) result in the transmitted data being stored by the server as state. There is no need to check for progress, success, or failure using an API read operation (GET) for these resources. The original response should communicate if the request was successful.
+
+Eventually consistent resources are asynchronous. For these resources, any changes you request will be applied over time. Requests to modify state using an API write operation (POST, PUT, PATCH or DELETE) result in the transmitted data being stored by the server and messages or events being generated to eventually apply this state. You may check for progress, success, or failure using an API read operation (GET). The original response communicates that the data resulting in instructions was understood by the system.
+
+## Resource Properties
+
+All NGINX Controller API resources contain the following properties:
+
+```json
+{
+ "metadata": {
+ },
+ "desiredState": {
+ },
+ "currentStatus": {
+ }
+}
+```
+
+The `desiredState` property is a representation of the state that you want to apply to the system. The properties within `desiredState` are the API representation of data. While changes to `desiredState` may trigger eventually consistent operations, the object itself is "immediately consistent". Consumers of the API can "read their own writes" and should always be able to retrieve the current desired state, no matter where the system is in the process of applying the state change.
+
+The `currentStatus` property represents the current state of the system. Its purpose is to communicate the progress of achieving eventual consistency to the API consumer. As such, `currentStatus` is a read-only property.
+
+## Versioning
+
+The introduction of backwards-incompatible changes to the NGINX Controller API constitutes a major version change. This will be represented in the NGINX Controller API version string. For example, to use a `v2` API, you would use `https:///api/v2`.
+
+When any NGINX Controller component requires a version change, we will release a new version of the entire API. In other words, you won't see a mix of `v1` and `v2` objects in the same API.
+
+{{< versions "3.0" "latest" "ctrlvers" >}}
+{{< versions "3.18" "latest" "apimvers" >}}
+{{< versions "3.20" "latest" "adcvers" >}}
diff --git a/content/controller/api/reference/ctlr-adc-api.md b/content/controller/api/reference/ctlr-adc-api.md
new file mode 100644
index 000000000..94af14cb5
--- /dev/null
+++ b/content/controller/api/reference/ctlr-adc-api.md
@@ -0,0 +1,16 @@
+---
+description:
+ Represents the state of the F5 NGINX Controller Application Delivery REST
+ API.
+docs: DOCS-1280
+doctypes:
+ - reference
+type: redoc
+tags:
+ - api
+title: ADC API
+toc: false
+weight: 300
+---
+
+{{< openapi spec="/controller/api/reference/ctlr-adc-openapi.json" >}}
diff --git a/content/controller/api/reference/ctlr-adc-openapi.json b/content/controller/api/reference/ctlr-adc-openapi.json
new file mode 100644
index 000000000..019f99da3
--- /dev/null
+++ b/content/controller/api/reference/ctlr-adc-openapi.json
@@ -0,0 +1,13365 @@
+{
+ "openapi": "3.0.0",
+ "info":{
+ "title": "NGINX Controller Application Delivery REST API",
+ "version": "v1",
+ "description": "Use the NGINX Controller Application Delivery module to configure, secure, monitor, and troubleshoot load balancing for your applications."
+ },
+ "servers": [
+ {
+ "description": "NGINX Controller API",
+ "url": "https://{{CONTROLLER_FQDN}}/api/v1"
+ }],
+ "tags": [
+ {
+ "name": "Instances",
+ "description": "Use the Instance API to manage NGINX Controller Instance resources."
+ },
+ {
+ "name": "Instance Groups",
+ "description": "Use the Instance Groups API to manage a set of instances that can be used for scaling and high availability. The Instance Groups API is a beta feature and is not recommended for use in production environments."
+ },
+ {
+ "name": "Instance Templates",
+ "description": "Use the Instance Templates API to manage templates that can be used to deploy new NGINX Plus instances."
+ },
+ {
+ "name": "Locations",
+ "description": "Use the Locations API to manage the deployment locations for NGINX Controller."
+ },
+ {
+ "name": "Integrations",
+ "description": "Use the Integrations API to manage integrated cloud provider accounts."
+ },
+ {
+ "name": "Environments",
+ "description": "Use the Environments API to manage your Application Environments."
+ },
+ {
+ "name": "Certs",
+ "description": "Use the Certs API to manage the certificates used to secure your App traffic."
+ },
+ {
+ "name": "Gateways",
+ "description": "Use the Gateways API to manage Gateway resources."
+ },
+ {
+ "name": "Apps",
+ "description": "Use the Apps API to manage App resources."
+ },
+ {
+ "name": "Components",
+ "description": "Use the Components API to define child components (for example, microservices) for your Apps."
+ },
+ {
+ "name": "API Definitions",
+ "description": "Use the API Definitions API to manage your APIs by using the NGINX Controller API Management module."
+ },
+ {
+ "name": "DevPortals",
+ "description": "Use the DevPortals API to manage DevPortals resources."
+ },
+ {
+ "name": "Identity Providers",
+ "description": "Use the Identity Provider API to manage Identity providers in the API-M Credential Management partition."
+ },
+ {
+ "name": "Published APIs",
+ "description": "Use the Published APIs API to manage your APIs by using the API Management module."
+ },
+ {
+ "name": "Error Sets",
+ "description": "Use the Error Sets API to view the default predefined Error Sets."
+ },
+ {
+ "name": "Services",
+ "description": "Use the Services API to request a metadata list of a desired resource within a single environment or across all environments.\nSupported resources:\n - published-apis\n"
+ },
+ {
+ "name": "Strategies",
+ "description": "Manage Security Strategies for your Apps and APIs. The current supported strategy is an NGINX App Protect Strategy (beta)."
+ },
+ {
+ "name": "Policies",
+ "description": "Manage Security Policies for your Apps and APIs. The current supported policy is an NGINX App Protect Policy (beta)."
+ }
+ ],
+ "paths": {
+ "/infrastructure/instance-groups": {
+ "get": {
+ "tags": [
+ "Instance Groups"
+ ],
+ "summary": "List Instance Groups",
+ "description": "Returns an unfiltered list of all Instance Group resources.",
+ "operationId": "listInstanceGroups",
+ "responses": {
+ "200": {
+ "description": "Successfully retieved a list of all the configured Instance Groups.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListInstanceGroupsResponse"
+ },
+ "example": {
+ "value": {
+ "items": [
+ {
+ "currentStatus": {
+ "instanceRefs": [],
+ "state": {
+ "conditions": [],
+ "selfConfigState": {
+ "configured": 1,
+ "configuring": 0,
+ "deleting": 0,
+ "error": 0,
+ "isConfigured": true,
+ "isConfiguring": false,
+ "isDeleting": false,
+ "isError": false,
+ "total": 1
+ }
+ }
+ },
+ "desiredState": {},
+ "metadata": {
+ "createTime": "2020-05-13T09:29:49.464273Z",
+ "description": "us-west-2 autoscale group",
+ "displayName": "aws-autoscale-group",
+ "kind": "instance-group",
+ "links": {
+ "rel": "/api/v1/infrastructure/instance-groups/amz-us-west-2-as-group"
+ },
+ "name": "amz-us-west-2-as-group",
+ "uid": "802ef1f8-9105-474a-b9a7-599837efd6b4",
+ "updateTime": "2020-05-13T09:29:49.464273Z"
+ }
+ },
+ {
+ "currentStatus": {
+ "instanceRefs": [
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/30dc361a3729"
+ },
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/01a9eead50e5"
+ }
+ ],
+ "state": {
+ "conditions": [],
+ "selfConfigState": {
+ "configured": 1,
+ "configuring": 0,
+ "deleting": 0,
+ "error": 0,
+ "isConfigured": true,
+ "isConfiguring": false,
+ "isDeleting": false,
+ "isError": false,
+ "total": 1
+ }
+ }
+ },
+ "desiredState": {},
+ "metadata": {
+ "createTime": "2020-05-13T16:58:17.058124Z",
+ "description": "K8S NGINX+ deployment",
+ "displayName": "k8s-nginx-deploy",
+ "kind": "instance-group",
+ "links": {
+ "rel": "/api/v1/infrastructure/instance-groups/k8s-nginx-deploy"
+ },
+ "name": "k8s-nginx-deploy",
+ "uid": "97d06b70-0d00-4863-b86d-40ab29efefdc",
+ "updateTime": "2020-05-13T16:58:17.058124Z"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Instance Groups"
+ ],
+ "summary": "Create an Instance Group",
+ "description": "Creates an new Instance Group resource.",
+ "operationId": "addInstanceGroup",
+ "requestBody": {
+ "description": "Defines the Instance Group resource to be added.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceGroup"
+ },
+ "example": {
+ "value": {
+ "metadata": {
+ "name": "k8s-nginx-deploy",
+ "displayName": "K8S NGINX+ deployment",
+ "description": "k8s-nginx-deploy"
+ },
+ "desiredState": {}
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "202": {
+ "description": "The Instance Group resource has been accepted for creation. The Instance Group will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceGroupResponse"
+ },
+ "example": {
+ "value": {
+ "metadata": {
+ "createTime": "2020-05-13T16:58:17.058124Z",
+ "description": "K8S NGINX+ deployment",
+ "displayName": "k8s-nginx-deploy",
+ "kind": "instance-group",
+ "links": {
+ "rel": "/api/v1/infrastructure/instance-groups/k8s-nginx-deploy"
+ },
+ "name": "k8s-nginx-deploy",
+ "uid": "97d06b70-0d00-4863-b86d-40ab29efefdc",
+ "updateTime": "2020-05-13T16:58:17.058124Z"
+ },
+ "desiredState": {},
+ "currentStatus": {
+ "instanceRefs": [
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/30dc361a3729"
+ },
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/01a9eead50e5"
+ }
+ ],
+ "state": {
+ "conditions": [],
+ "selfConfigState": {
+ "configured": 1,
+ "configuring": 0,
+ "deleting": 0,
+ "error": 0,
+ "isConfigured": true,
+ "isConfiguring": false,
+ "isDeleting": false,
+ "isError": false,
+ "total": 1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ }
+ },
+ "/infrastructure/instance-groups/{instanceGroupName}": {
+ "get": {
+ "tags": [
+ "Instance Groups"
+ ],
+ "summary": "Get an Instance Group",
+ "description": "Returns information about a specified Instance Groupe resource.",
+ "operationId": "getInstanceGroup",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/InstanceGroupName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Instance Group resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceGroupResponse"
+ },
+ "example": {
+ "value": {
+ "metadata": {
+ "createTime": "2020-05-13T16:58:17.058124Z",
+ "description": "K8S NGINX+ deployment",
+ "displayName": "k8s-nginx-deploy",
+ "kind": "instance-group",
+ "links": {
+ "rel": "/api/v1/infrastructure/instance-groups/k8s-nginx-deploy"
+ },
+ "name": "k8s-nginx-deploy",
+ "uid": "97d06b70-0d00-4863-b86d-40ab29efefdc",
+ "updateTime": "2020-05-13T16:58:17.058124Z"
+ },
+ "desiredState": {},
+ "currentStatus": {
+ "instanceRefs": [
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/30dc361a3729"
+ },
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/01a9eead50e5"
+ }
+ ],
+ "state": {
+ "conditions": [],
+ "selfConfigState": {
+ "configured": 1,
+ "configuring": 0,
+ "deleting": 0,
+ "error": 0,
+ "isConfigured": true,
+ "isConfiguring": false,
+ "isDeleting": false,
+ "isError": false,
+ "total": 1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Instance Groups"
+ ],
+ "summary": "Upsert an Instance Group",
+ "description": "Creates a new Instance Group resource or updates an existing Instance Group resource.",
+ "operationId": "upsertInstanceGroup",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/InstanceGroupName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceGroup"
+ },
+ "example": {
+ "value": {
+ "metadata": {
+ "name": "k8s-nginx-deploy",
+ "displayName": "K8S NGINX+ deployment",
+ "description": "k8s-nginx-deploy"
+ },
+ "desiredState": {}
+ }
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "202": {
+ "description": "The Instance Group resource has been accepted for creation or update.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceGroupResponse"
+ },
+ "example": {
+ "value": {
+ "metadata": {
+ "createTime": "2020-05-13T16:58:17.058124Z",
+ "description": "K8S NGINX+ deployment",
+ "displayName": "k8s-nginx-deploy",
+ "kind": "instance-group",
+ "links": {
+ "rel": "/api/v1/infrastructure/instance-groups/k8s-nginx-deploy"
+ },
+ "name": "k8s-nginx-deploy",
+ "uid": "97d06b70-0d00-4863-b86d-40ab29efefdc",
+ "updateTime": "2020-05-13T16:58:17.058124Z"
+ },
+ "desiredState": {},
+ "currentStatus": {
+ "instanceRefs": [
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/30dc361a3729"
+ },
+ {
+ "ref": "/infrastructure/locations/eks-cluster/instances/01a9eead50e5"
+ }
+ ],
+ "state": {
+ "conditions": [],
+ "selfConfigState": {
+ "configured": 1,
+ "configuring": 0,
+ "deleting": 0,
+ "error": 0,
+ "isConfigured": true,
+ "isConfiguring": false,
+ "isDeleting": false,
+ "isError": false,
+ "total": 1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Instance Groups"
+ ],
+ "summary": "Delete an Instance Group",
+ "description": "Deletes the specified Instance Group resource.",
+ "operationId": "deleteInstanceGroup",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/InstanceGroupName"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the specified Instance Group resource."
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ }
+ },
+ "/infrastructure/locations": {
+ "get": {
+ "tags": [
+ "Locations"
+ ],
+ "summary": "List all Locations",
+ "description": "Returns a list of all Locations.",
+ "operationId": "listLocations",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all of the configured Locations.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListLocationResponse"
+ },
+ "example": {
+ "value": {
+ "items": [
+ {
+ "currentStatus": {
+ "type": "OTHER_LOCATION"
+ },
+ "desiredState": {
+ "type": "OTHER_LOCATION"
+ },
+ "metadata": {
+ "createTime": "2020-05-13T09:29:49.464273Z",
+ "description": "Location for instances where location has not been specified",
+ "displayName": "Unspecified (default)",
+ "kind": "location",
+ "links": {
+ "rel": "/api/v1/infrastructure/locations/unspecified"
+ },
+ "name": "unspecified",
+ "tags": [
+ "default"
+ ],
+ "uid": "802ef1f8-9105-474a-b9a7-599837efd6b4",
+ "updateTime": "2020-05-13T09:29:49.464273Z"
+ }
+ },
+ {
+ "currentStatus": {
+ "type": "OTHER_LOCATION"
+ },
+ "desiredState": {
+ "type": "OTHER_LOCATION"
+ },
+ "metadata": {
+ "createTime": "2020-05-13T16:58:17.058124Z",
+ "description": "Other Location for managing instances",
+ "displayName": "OtherLocation-1",
+ "kind": "location",
+ "links": {
+ "rel": "/api/v1/infrastructure/locations/my-other-location"
+ },
+ "name": "my-other-location",
+ "tags": [
+ "dev",
+ "prod"
+ ],
+ "uid": "97d06b70-0d00-4863-b86d-40ab29efefdc",
+ "updateTime": "2020-05-13T16:58:17.058124Z"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Locations"
+ ],
+ "summary": "Create a Location",
+ "description": "Creates a new Location resource.",
+ "operationId": "addLocation",
+ "requestBody": {
+ "description": "Defines the Location resource to be added.",
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Location"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationRequest"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationRequest"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the requested Location.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetLocationResponse"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationResponse"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationResponse"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationResponse"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "405": {
+ "$ref": "#/components/responses/NotAllowed"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ }
+ },
+ "/infrastructure/locations/{locationName}": {
+ "get": {
+ "tags": [
+ "Locations"
+ ],
+ "summary": "Get a Location",
+ "description": "Returns information about a specified Location resource.",
+ "operationId": "getLocation",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Location resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetLocationResponse"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationResponse"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationResponse"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationResponse"
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Locations"
+ ],
+ "summary": "Upsert a Location",
+ "description": "Creates a new Location resource or updates an existing Location resource.",
+ "operationId": "upsertLocation",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Location"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationRequest"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationRequest"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationRequest"
+ }
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully received the request to update the specified Location resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetLocationResponse"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationResponse"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationResponse"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationResponse"
+ }
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully updated the specified Location resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetLocationResponse"
+ },
+ "examples": {
+ "OTHER_LOCATION": {
+ "$ref": "#/components/examples/OtherLocationResponse"
+ },
+ "AWS_LOCATION": {
+ "$ref": "#/components/examples/AWSLocationResponse"
+ },
+ "AZURE_LOCATION": {
+ "$ref": "#/components/examples/AzureLocationResponse"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "405": {
+ "$ref": "#/components/responses/NotAllowed"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Locations"
+ ],
+ "summary": "Delete a Location",
+ "description": "Deletes the specified Location resource.",
+ "operationId": "deleteLocation",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the specified Location resource."
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ },
+ "405": {
+ "$ref": "#/components/responses/NotAllowed"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ }
+ },
+ "/infrastructure/locations/{locationName}/instances": {
+ "get": {
+ "tags": [
+ "Instances"
+ ],
+ "summary": "List all Instances in a Location",
+ "description": "Returns the status and metadata for all of the Instances in the specified Location.",
+ "operationId": "listInstances",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully returned the status and metadata for all of the Instances in the specified Location.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListInstanceResponse"
+ },
+ "examples": {
+ "INSTANCES": {
+ "$ref": "#/components/examples/ListInstanceResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Instances"
+ ],
+ "summary": "Create an Instance",
+ "description": "Creates a new Instance resource.",
+ "operationId": "createInstance",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceRequest"
+ },
+ "examples": {
+ "AWS_INSTANCE": {
+ "$ref": "#/components/examples/AWSInstanceRequest"
+ },
+ "AZURE_INSTANCE": {
+ "$ref": "#/components/examples/AzureInstanceRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "202": {
+ "description": "The Instance resource has been accepted for creation. The Instance will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceResponse"
+ },
+ "examples": {
+ "AWS_INSTANCE": {
+ "$ref": "#/components/examples/AWSInstance"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter or URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error creating the instance: could not parse the request payload. Check the format of the request, then try again.",
+ "code": 120647
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a conflict with an existing Instance resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error creating the instance: the instance already exists. Use a unique name for the instance, then try again.",
+ "code": 120652
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/infrastructure/locations/{locationName}/instances/{instanceName}": {
+ "get": {
+ "tags": [
+ "Instances"
+ ],
+ "summary": "Get an Instance",
+ "description": "Returns the status and metadata for a single Instance.",
+ "operationId": "getInstance",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully returned the details for an Instance.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceResponse"
+ },
+ "examples": {
+ "OTHER_INSTANCE": {
+ "$ref": "#/components/examples/OtherInstance"
+ },
+ "AWS_INSTANCE": {
+ "$ref": "#/components/examples/AWSInstance"
+ },
+ "AZURE_INSTANCE": {
+ "$ref": "#/components/examples/AzureInstance"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Instance not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error getting the instance: the specified instance does not exist. Check the instance name, then try again.",
+ "code": 120603
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Instances"
+ ],
+ "summary": "Update an Instance",
+ "description": "Updates the description or display name of an existing Instance.",
+ "operationId": "updateInstance",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceRequest"
+ },
+ "examples": {
+ "OTHER_INSTANCE": {
+ "$ref": "#/components/examples/InstanceUpdateRequest"
+ },
+ "AWS_INSTANCE": {
+ "$ref": "#/components/examples/InstanceUpdateRequest"
+ },
+ "AZURE_INSTANCE": {
+ "$ref": "#/components/examples/InstanceUpdateRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the existing Instance.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceResponse"
+ },
+ "examples": {
+ "OTHER_INSTANCE": {
+ "$ref": "#/components/examples/OtherInstance"
+ },
+ "AWS_INSTANCE": {
+ "$ref": "#/components/examples/AWSInstance"
+ },
+ "AZURE_INSTANCE": {
+ "$ref": "#/components/examples/AzureInstance"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter or URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error updating the instance: could not parse the request payload. Check the format of the request, then try again.",
+ "code": 120612
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Instance not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error updating the instance: the specified instance does not exist. Check the instance name, then try again.",
+ "code": 120614
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Instances"
+ ],
+ "summary": "Delete an Instance",
+ "operationId": "deleteInstance",
+ "description": "Deletes the specified Instance.",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceName"
+ }
+ ],
+ "responses": {
+ "202": {
+ "description": "Request for delete accepted",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceResponse"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the Instance. No content is returned."
+ },
+ "404": {
+ "description": "Instance not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error deleting the instance: the specified instance does not exist. Check the instance name, then try again.",
+ "code": 120609
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the requested Instance resource.\n\nThe Instance is referenced by another resource. Remove the references to the Instance, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ },
+ "example": {
+ "message": "Error deleting the instance: the NGINX instance is being configured. Try again later. If the problem persists, contact the system administrator.",
+ "code": 120640
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/infrastructure/locations/{locationName}/instance-templates": {
+ "get": {
+ "tags": [
+ "Instance Templates"
+ ],
+ "summary": "List Instance Templates",
+ "description": "Returns an unfiltered list of all Instance Template resources in the specified Location.",
+ "operationId": "listInstanceTemplates",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all Instance Template resources for the specified Location.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListInstanceTemplateResponse"
+ },
+ "examples": {
+ "INSTANCE_TEMPLATES": {
+ "$ref": "#/components/examples/AWSListResponse"
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Instance Templates"
+ ],
+ "summary": "Create an Instance Template",
+ "description": "Creates a new Instance Template resource.",
+ "operationId": "addInstanceTemplate",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ }
+ ],
+ "requestBody": {
+ "description": "Defines the Instance Template resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceTemplate"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSRequest"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureRequestWithMarketplaceImageAndUsingExistingNic"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the requested Instance Template resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceTemplateResponse"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSResponse"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureResponse"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ }
+ },
+ "/infrastructure/locations/{locationName}/instance-templates/{instanceTemplateName}": {
+ "get": {
+ "tags": [
+ "Instance Templates"
+ ],
+ "summary": "Get an Instance Template",
+ "description": "Gets information for the specified Instance Template resource.",
+ "operationId": "getInstanceTemplate",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceTemplateName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Instance Template resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceTemplateResponse"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSResponse"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureResponse"
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Instance Templates"
+ ],
+ "summary": "Upsert an Instance Template",
+ "description": "Creates a new Instance Template resource or updates an existing Instance Template resource.",
+ "operationId": "upsertInstanceTemplate",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceTemplateName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/InstanceTemplate"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSRequest"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureRequestWithCustomImageAndCreatingNewNicAndPublicIP"
+ }
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Instance Template resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceTemplateResponse"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSResponse"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureResponse"
+ }
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Instance Template resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetInstanceTemplateResponse"
+ },
+ "examples": {
+ "AWS_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AWSResponse"
+ },
+ "AZURE_INSTANCE_TEMPLATE": {
+ "$ref": "#/components/examples/AzureResponse"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "$ref": "#/components/responses/BadRequest"
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "409": {
+ "$ref": "#/components/responses/Conflict"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Instance Templates"
+ ],
+ "summary": "Delete an Instance Template",
+ "description": "Deletes the specified Instance Template resource.",
+ "operationId": "deleteInstanceTemplate",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/LocationName"
+ },
+ {
+ "$ref": "#/components/parameters/InstanceTemplateName"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the specified Instance Template resource."
+ },
+ "401": {
+ "$ref": "#/components/responses/Unauthorized"
+ },
+ "404": {
+ "$ref": "#/components/responses/NotFound"
+ }
+ }
+ }
+ },
+ "/platform/integrations": {
+ "get": {
+ "tags": [
+ "Integrations"
+ ],
+ "summary": "List all Integrations",
+ "description": "Returns an unfiltered list of account Integrations.",
+ "operationId": "listIntegrations",
+ "responses": {
+ "200": {
+ "description": "Successfully retreived all Integration accounts.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListIntegrationResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Integrations"
+ ],
+ "summary": "Create an Integration account",
+ "description": "Creates a new Integration account.",
+ "operationId": "addIntegration",
+ "requestBody": {
+ "description": "Defines the Integration account to be added.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Integration"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the requested Integration.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetIntegrationResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a conflict with an existing Integration.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/platform/integrations/{integrationName}": {
+ "get": {
+ "tags": [
+ "Integrations"
+ ],
+ "summary": "Get an Integration account",
+ "description": "Gets information about a specific Integration account.",
+ "operationId": "getIntegration",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/IntegrationName"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Integration account.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetIntegrationResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Integration not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Integrations"
+ ],
+ "summary": "Update an Integration account",
+ "description": "Updates an Integration account.",
+ "operationId": "updateIntegration",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/IntegrationName"
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Integration"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully received the request to update the specified Integration account.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetIntegrationResponse"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully updated the specified Integration account.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetIntegrationResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Integrations"
+ ],
+ "summary": "Delete an Integration account",
+ "description": "Deletes the specified Integration account resource.",
+ "operationId": "deleteIntegration",
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/IntegrationName"
+ }
+ ],
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the specified Integration resource."
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/services/environments": {
+ "get": {
+ "tags": [
+ "Environments"
+ ],
+ "summary": "List all Environments",
+ "description": "Returns a list of all Environment resources.\n",
+ "operationId": "listEnvironments",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all Environment resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Environments"
+ ],
+ "summary": "Create an Environment",
+ "description": "Creates a new Environment resource.\n",
+ "operationId": "createEnvironment",
+ "requestBody": {
+ "description": "Defines the Environment resource to create.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified Environment.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Environment resource has been accepted for creation. The Environment will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/services/environments/{environmentName}": {
+ "get": {
+ "tags": [
+ "Environments"
+ ],
+ "summary": "Get an Environment",
+ "description": "Returns information for the specified Environment.\n",
+ "operationId": "getEnvironment",
+ "responses": {
+ "200": {
+ "description": "Successfully returned information for the specified Environment resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Environments"
+ ],
+ "summary": "Upsert an Environment",
+ "description": "Creates a new Environment or updates an existing Environment resource.\n",
+ "operationId": "updateEnvironment",
+ "requestBody": {
+ "description": "Defines the Environment to create or the updates to make to an existing Environment.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Environment resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified Environment resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Environment resource has been accepted for creation or update. The Environment will be created or updated after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Environments"
+ ],
+ "summary": "Delete an Environment",
+ "description": "Deletes the specified Environment resource.",
+ "operationId": "deleteEnvironment",
+ "responses": {
+ "202": {
+ "description": "The Environment resource has been marked for deletion. The Environment will be deleted after the underlying resources have been deleted.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Environment resource. No content returned.\n"
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the requested Environment resource.\n\nThe Environment contains references to other objects. Delete the referenced objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/certs": {
+ "get": {
+ "tags": [
+ "Certs"
+ ],
+ "summary": "List all Certs",
+ "description": "Returns a list of Cert metadata objects for all of the Certs in the specified environment.",
+ "operationId": "listCerts",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Certs for the specified Environment.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CertList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Certs"
+ ],
+ "summary": "Create a Cert",
+ "operationId": "createCert",
+ "description": "Creates a new Cert resource in the specified Environment.\n",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Cert"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified Cert resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CertStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Cert.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/certs/{certName}": {
+ "get": {
+ "tags": [
+ "Certs"
+ ],
+ "summary": "Get a Cert",
+ "operationId": "getCert",
+ "description": "Returns information for a specific Cert resource.",
+ "responses": {
+ "200": {
+ "description": "Sucessfully retrieved the requested Cert.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CertStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Certs"
+ ],
+ "summary": "Upsert a Cert",
+ "operationId": "updateCert",
+ "description": "Creates a new Cert or updates an existing Cert resource.",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Cert"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Sucessfully updated the specified Cert resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CertStatus"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Cert resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CertStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Certs"
+ ],
+ "summary": "Delete a Cert",
+ "operationId": "deleteCert",
+ "description": "Deletes the specified Cert resource.",
+ "responses": {
+ "204": {
+ "description": "The specified Cert resource was successfully deleted."
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete the specified Cert resource failed.\nThe Cert is referenced by active objects and cannot be deleted. Delete the referencing objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Cert.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "certName",
+ "description": "The name of the Cert.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/ResourceName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/gateways": {
+ "get": {
+ "tags": [
+ "Gateways"
+ ],
+ "summary": "List all Gateways",
+ "description": "Returns a list of all Gateways in the specified Environment.\n",
+ "operationId": "listGateways",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all Gateways for the specified Environment.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GatewayList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Gateways"
+ ],
+ "summary": "Create a Gateway",
+ "description": "Creates a new Gateway resource.\n",
+ "operationId": "createGateway",
+ "requestBody": {
+ "description": "Defines the Gateway resource to create.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified Gateway resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Gateway resource has been accepted for creation. The Gateway will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to create a Gateway resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Gateway resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/gateways/{gatewayName}": {
+ "get": {
+ "tags": [
+ "Gateways"
+ ],
+ "summary": "Get a Gateway",
+ "description": "Returns information for the specified Gateway resource.\n",
+ "operationId": "getGateway",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Gateway resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Gateways"
+ ],
+ "summary": "Upsert a Gateway",
+ "description": "Creates a new Gateway or updates an existing Gateway resource.\n",
+ "operationId": "updateGateway",
+ "requestBody": {
+ "description": "Defines the Gateway resource to create or the updates to make to an existing Gateway resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Gateway resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified Gateway resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Gateway resource has been accepted for creation or update. The Gateway will be created or updated after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to update or create a Gateway resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Gateways"
+ ],
+ "summary": "Delete a Gateway",
+ "description": "Deletes the specified Gateway resource.",
+ "operationId": "deleteGateway",
+ "responses": {
+ "202": {
+ "description": "The Gateway resource has been marked for deletion. The Gateway will be deleted after the underlying resources have been deleted.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Gateway resource. No content is returned.\n"
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete a Gateway resource failed.\nThe Gateway is referenced by an App Component(s) and cannot be deleted.\nDelete the App Component or remove the reference, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to delete a Gateway resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Gateway resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "gatewayName",
+ "description": "The name of the Gateway.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/GatewayName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps": {
+ "get": {
+ "tags": [
+ "Apps"
+ ],
+ "summary": "List all Apps",
+ "description": "Returns a list of all App resources.\n",
+ "operationId": "listApps",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all App resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AppList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Apps"
+ ],
+ "summary": "Create an App",
+ "description": "Creates a new App resource.",
+ "operationId": "createApp",
+ "requestBody": {
+ "description": "An App.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified App resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The App resource has been accepted for creation. The App will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps/{appName}": {
+ "get": {
+ "tags": [
+ "Apps"
+ ],
+ "summary": "Get an App",
+ "description": "Gets the information for a specific App resource.\n",
+ "operationId": "getApp",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved information for the requested App resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Apps"
+ ],
+ "summary": "Upsert an App",
+ "description": "Creates a new App resource or updates an existing App resource.\n",
+ "operationId": "updateApp",
+ "requestBody": {
+ "description": "Defines the App resource to create or update.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified App resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified App resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The App resource has been accepted for creation or update. The App will be created or updated after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Apps"
+ ],
+ "summary": "Delete an App",
+ "description": "Deletes the specified App resource.\n\nYou must delete all of an App's child resources before you delete the App.\n",
+ "operationId": "deleteApp",
+ "responses": {
+ "202": {
+ "description": "The App resource has been marked for deletion. The App will be deleted after the underlying resources have been deleted.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified App resource.\n"
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete the specified App resource failed.\nThe App contains references to active objects and cannot be deleted. Delete the child objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "appName",
+ "description": "The name of the App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/AppName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps/{appName}/components": {
+ "get": {
+ "tags": [
+ "Components"
+ ],
+ "summary": "List all Components",
+ "description": "Returns a list of all of the Component resources that are contained by the specified App.\n",
+ "operationId": "listAppComponents",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Component resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ComponentList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "strategyName",
+ "in": "query",
+ "description": "Filter desired component based on the strategy.",
+ "required": false,
+ "style": "form",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "policyName",
+ "in": "query",
+ "description": "Filter desired component based on the policy.",
+ "required": false,
+ "style": "form",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "Components"
+ ],
+ "summary": "Create a Component",
+ "description": "Creates a new Component resource.\n",
+ "operationId": "createAppComponent",
+ "requestBody": {
+ "description": "Defines the Component resource to create.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ },
+ "examples": {
+ "ComponentRequest": {
+ "$ref": "#/components/examples/ComponentRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the requested Component resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Component resource has been accepted for creation. The Component will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to create a Component resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Component's parent App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "appName",
+ "description": "The name of the App that contains the Component resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/AppName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps/{appName}/components/{componentName}": {
+ "get": {
+ "tags": [
+ "Components"
+ ],
+ "summary": "Get a Component",
+ "description": "Returns information for the specified Component.\n",
+ "operationId": "getAppComponent",
+ "responses": {
+ "200": {
+ "description": "Successfully returned the requested Component resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Components"
+ ],
+ "summary": "Upsert a Component",
+ "description": "Creates a new Component or updates an existing Component resource.\n",
+ "operationId": "updateAppComponent",
+ "requestBody": {
+ "description": "Defines the Component resource to create or update.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ },
+ "examples": {
+ "ComponentRequest": {
+ "$ref": "#/components/examples/ComponentRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Component resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified Component resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Component resource has been accepted for creation or update. The Component will be created or updated after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to update or create a Component resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Components"
+ ],
+ "summary": "Delete a Component",
+ "description": "Deletes the specified Component resource.",
+ "operationId": "deleteAppComponent",
+ "responses": {
+ "202": {
+ "description": "Component resource has been marked for deletion. The resource will be\ndeleted after the underlying resources have been freed.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Component. No content returned.\n"
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to delete a Component resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Component's parent App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "appName",
+ "description": "The name of the App that contains the Component resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/AppName"
+ }
+ },
+ {
+ "name": "componentName",
+ "description": "The name of the Component resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/ComponentName"
+ }
+ }
+ ]
+ },
+ "/services": {
+ "x-f5-experimental": true,
+ "get": {
+ "tags": [
+ "Services"
+ ],
+ "summary": "List the metadata for all instances of the desired resource.",
+ "description": "Returns a metadata list of the requested resource. The resources that can be queried is currently restricted to published-apis.\n",
+ "operationId": "listResources",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a metadata list of the requested resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "The resource defined in the query parameters could not be found or is not yet supported. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The environment defined in the query parameters could not be found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "resource",
+ "in": "query",
+ "description": "Desired resource to list.",
+ "required": true,
+ "style": "form",
+ "explode": false,
+ "schema": {
+ "type": "string",
+ "enum": [
+ "published-apis"
+ ]
+ }
+ },
+ {
+ "name": "environment",
+ "in": "query",
+ "description": "Filter desired resource based on the environment.",
+ "required": false,
+ "style": "form",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "/services/api-definitions": {
+ "get": {
+ "tags": [
+ "API Definitions"
+ ],
+ "summary": "List API Definitions",
+ "description": "Returns a list of API Definition resources.",
+ "operationId": "apiDefinitionsSearch",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all API Definitions.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionList"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/services/api-definitions/{apiDefinitionName}": {
+ "get": {
+ "tags": [
+ "API Definitions"
+ ],
+ "summary": "Get an API Definition",
+ "description": "Gets information about a specified API Definition.\n",
+ "operationId": "apiDefinitionsGet",
+ "responses": {
+ "200": {
+ "description": "Successfully returned the specified API Definition resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinition"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified API Definition resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "API Definitions"
+ ],
+ "summary": "Upsert an API Definition",
+ "description": "Creates a new API Definition or updates an existing API Definition resource.\n",
+ "operationId": "apiDefinitionsPut",
+ "requestBody": {
+ "description": "Defines the API Definition resource to create, or the updates to apply to an existing API Definition resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinition"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified API Definition resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinition"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested API Definition resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinition"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "API Definitions"
+ ],
+ "summary": "Delete an API Definition",
+ "description": "Deletes the specified API Definition resource.",
+ "operationId": "apiDefinitionsDelete",
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the requested API Definition resource. No content is returned.\n"
+ },
+ "404": {
+ "description": "The specified API Definition resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the specified API Definition resource. Delete any referenced Published APIs or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/apiDefinitionName"
+ }
+ ]
+ },
+ "/services/api-definitions/{apiDefinitionName}/versions": {
+ "get": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "List API Definition Versions",
+ "description": "Lists all Versions for the specified API Definition resource.\n",
+ "operationId": "definitionVersionsSearch",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the list of API Definition Version resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersionList"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified API Definition resource was not found or does not contain any Versions.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "Add an API Definition Version",
+ "description": "Creates a single new API Definition Version resource or multiple Version resources.\n",
+ "operationId": "definitionVersionsPutList",
+ "requestBody": {
+ "description": "Creates, updates, or deletes an API Definition Version resource. It interacts with a list of items.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersionList"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully received the request to create the API Definition Version resource(s).",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersionList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the specified API Definition Version resource(s) as it has at least one dependent Published API. Delete the referenced Published API(s), then try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "Delete API Definition Versions",
+ "description": "Deletes all Versions for the specified API Definition resource.\n",
+ "operationId": "definitionVersionsDeleteList",
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the Versions for the requested API Definition resource. No content is returned.\n"
+ },
+ "404": {
+ "description": "The specified API Definition resource was not found or does not contain any Versions.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the Versions for the specified API Definition resource. Delete or remove any references to Published APIs, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/apiDefinitionName"
+ }
+ ]
+ },
+ "/services/api-definitions/{apiDefinitionName}/versions/{version}": {
+ "get": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "Get an API Definition Version",
+ "description": "Gets information about an API Definition Version resource.\n",
+ "operationId": "definitionVersionsGet",
+ "responses": {
+ "200": {
+ "description": "Successfully returned the specified API Definition Version resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified API Definition Version resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "Upsert an API Definition Version",
+ "description": "Creates a single new Version resource or updates an existing API Definition Version resource.\n",
+ "operationId": "definitionVersionsPut",
+ "requestBody": {
+ "description": "Creates or updates an API Definition Version resource",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified API Definition Version resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested API Definition Version resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "API Definition Versions"
+ ],
+ "summary": "Delete an API Definition Version",
+ "description": "Deletes an API Definition Version resource.\n",
+ "operationId": "definitionVersionsDelete",
+ "responses": {
+ "204": {
+ "description": "Successfully deleted the API Definition Version resource.\n"
+ },
+ "404": {
+ "description": "The specified API Definition Version resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "Failed to delete the specified API Definition resource. Delete or remove any references to Published APIs, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/apiDefinitionName"
+ },
+ {
+ "$ref": "#/components/parameters/versionName"
+ }
+ ]
+ },
+ "/services/api-definitions/{apiDefinitionName}/versions/{version}/import": {
+ "put": {
+ "tags": [
+ "API Definition Version Import"
+ ],
+ "summary": "Import an API Definition Version",
+ "description": "Imports an API spec to the specified Version of an API Definition.\n\nUse this endpoint to import a raw API specification to define your API.\n\n- This endpoint accepts a valid OpenAPI 3 spec, formatted as valid JSON or YAML.\n- The file provided for import will be validated against the\n [OAS v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v3.0/schema.yaml).\n- You must specify a \"Content-Type\" header when importing an API spec.\n The endpoint accepts the following \"Content-Type\" values:\n\n - application/json\n - application/yaml\n - text/x-yaml\n - application/x-yaml\n - text/yaml\n",
+ "operationId": "definitionVersionsImport",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object"
+ }
+ },
+ "application/yaml": {
+ "schema": {
+ "type": "string"
+ }
+ },
+ "text/x-yaml": {
+ "schema": {
+ "type": "string"
+ }
+ },
+ "application/x-yaml": {
+ "schema": {
+ "type": "string"
+ }
+ },
+ "text/yaml": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully completed the API Version Import request.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested API Definition Version resource from the spec provided.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "415": {
+ "description": "The request body contains an unsupported content type.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/apiDefinitionName"
+ },
+ {
+ "$ref": "#/components/parameters/versionName"
+ }
+ ]
+ },
+ "/security/identity-providers": {
+ "get": {
+ "tags": [
+ "Identity Providers"
+ ],
+ "summary": "List Identity Providers",
+ "description": "Returns a list of all Identity Provider resources.\n\n> **Note:** These resources were known as Client Groups in pre-3.x versions of NGINX Controller.\n",
+ "operationId": "identityProvidersSearch",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Identity Provider resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/security/identity-providers/{identityProviderName}": {
+ "get": {
+ "tags": [
+ "Identity Providers"
+ ],
+ "summary": "Get an Identity Provider",
+ "description": "Returns the specified Identity Provider resource.",
+ "operationId": "identityProvidersGet",
+ "responses": {
+ "200": {
+ "description": "Successfully returnd the specified Identity Provider resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "The request failed due to insufficient privileges.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "The request cannot be processed because of an internal server error.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Identity Providers"
+ ],
+ "summary": "Upsert an Identity Provider",
+ "description": "Creates a new Identity Provider, or creates an existing Identity Provider resource.\n",
+ "operationId": "identityProvidersPut",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ },
+ "examples": {
+ "IdentityProviderRequest": {
+ "$ref": "#/components/examples/IdentityProviderRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Identity Provider resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Identity Provider resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "Successfully accepted the requested Identity Provider resource and is currently processing it.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to update or create an Identity Provider resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Identity Providers"
+ ],
+ "summary": "Delete an Identity Provider",
+ "description": "Deletes the specified Identity Provider resource.",
+ "operationId": "identityProvidersDelete",
+ "responses": {
+ "202": {
+ "description": "The Identity Provider resource has been marked for deletion. The resource will be deleted after the publish/cleanup succeeds.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Identity Provider resource. No content is returned."
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to delete an Identity Provider resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "The request cannot be processed because of an internal server error.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/identityProviderName"
+ }
+ ]
+ },
+ "/security/identity-providers/{identityProviderName}/clients": {
+ "get": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "List Identity Provider Clients",
+ "description": "Returns a list of all Identity Provider Client resources.\n",
+ "operationId": "identityProviderClientsSearch",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Identity Provider Client resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClientList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "Create Multiple Identity Provider Clients",
+ "description": "Creates or updates multiple Identity Provider Client resources.\n",
+ "operationId": "identityProviderClientsPutList",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClientList"
+ },
+ "examples": {
+ "IdentityProviderClientListRequest": {
+ "$ref": "#/components/examples/IdentityProviderClientListRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully upserted the Identity Provider Client resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClientList"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "Successfully accepted the requested Identity Provider Client resources and is currently processing it.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClientList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The Identity Provider Client resource conflicts with another resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/identityProviderName"
+ }
+ ]
+ },
+ "/security/identity-providers/{identityProviderName}/clients/{identityProviderClientName}": {
+ "get": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "Get an Identity Provider Client",
+ "description": "Returns information for the specified Identity Provider Client resource.",
+ "operationId": "identityProviderClientsGet",
+ "responses": {
+ "200": {
+ "description": "Successfully returned the specified Identity Provider Client resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider Client resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "Update an Identity Provider Client",
+ "description": "Updates the specified Identity Provider Client resource.",
+ "operationId": "identityProviderClientsPut",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ },
+ "examples": {
+ "IdentityProviderClientRequest": {
+ "$ref": "#/components/examples/IdentityProviderClientRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Identity Provider Client resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified Identity Provider Client resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "Successfully accepted the requested Identity Provider Client resource and is currently processing it.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to update or create an Identity Provider Client resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "Update an Identity Provider Client",
+ "description": "Updates the specified Identity Provider Client resource.",
+ "operationId": "identityProviderClientsPatch",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateIdentityProviderClient"
+ },
+ "examples": {
+ "IdentityProviderClientPatchMetadataRequest": {
+ "$ref": "#/components/examples/IdentityProviderClientPatchMetadataRequest"
+ },
+ "IdentityProviderClientPatchDesiredStateRequest": {
+ "$ref": "#/components/examples/IdentityProviderClientPatchDesiredStateRequest"
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Identity Provider Client resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "Successfully accepted the request to update an Identity Provider Client resource and is currently processing it.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider Client resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to update an Identity Provider Client resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Identity Provider Clients"
+ ],
+ "summary": "Delete an Identity Provider Client",
+ "description": "Deletes the specified Identity Provider Client resource.",
+ "operationId": "identityProviderClientsDelete",
+ "responses": {
+ "202": {
+ "description": "Identity Provider Client resource has been marked for deletion. The resource will be\ndeleted after the publish/cleanup succeeds.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Identity Provider Client resource. No content is returned."
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Identity Provider Client resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "429": {
+ "description": "The request to delete an Identity Provider Client resource failed due to exceeding request processing threshold.\nAllow the server to process existing requests, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/identityProviderName"
+ },
+ {
+ "$ref": "#/components/parameters/identityProviderClientName"
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/devportals": {
+ "get": {
+ "tags": [
+ "DevPortals"
+ ],
+ "summary": "List all DevPortals",
+ "description": "Returns a list of all DevPortal resources.\n",
+ "operationId": "ListDevPortals",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of all DevPortals resources.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DevPortalsList"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Illegal input parameter or malformed URI specified. Check for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "DevPortals"
+ ],
+ "summary": "Create DevPortal",
+ "description": "Creates new Dev Portal resource.",
+ "operationId": "CreateDevPortal",
+ "requestBody": {
+ "description": "A Dev Portal.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created a specified Dev Portal resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "Dev Portal resource has been accepted for creation. A Dev Portal will be created after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Illegal input parameter or malformed URI specified. Check for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the DevPortal.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/devportals/{devPortalName}": {
+ "get": {
+ "tags": [
+ "DevPortals"
+ ],
+ "summary": "Get Dev Portal",
+ "description": "Gets the information for a specific Dev Portal resource.\n",
+ "operationId": "GetDevPortal",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved information for the requested Dev Portal resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Illegal input parameter or malformed URI specified. Check for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "DevPortals"
+ ],
+ "summary": "Upsert Dev Portal",
+ "description": "Creates a new Dev Portal resource or updates an existing Dev Portal resource.\n",
+ "operationId": "UpsertDevPortal",
+ "requestBody": {
+ "description": "Defines a Dev Portal resource to create or update.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Dev Portal resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the specified Dev Portal resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The Dev Portal resource has been accepted for creation or update. Dev Portal will be created or updated after it is done configuring.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Illegal input parameter or malformed URI specified. Check for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "DevPortals"
+ ],
+ "summary": "Delete a DevPortal",
+ "description": "Deletes the specified Dev Portal resource.\nYou must delete all of a Dev Portal's child resources before you delete the Dev Portal.\n",
+ "operationId": "DeleteDevPortal",
+ "responses": {
+ "202": {
+ "description": "The DevPortal resource has been marked for deletion. DevPortal will be deleted after the underlying resources have been deleted.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified DevPortal resource.\n"
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete the specified App resource failed.\nThe App contains references to active objects and cannot be deleted. Delete the child objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the DevPortal.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ {
+ "name": "devPortalName",
+ "description": "The name of the DevPortal.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "/services/errorsets": {
+ "get": {
+ "tags": [
+ "Error Sets"
+ ],
+ "summary": "List all Error Sets.",
+ "description": "Returns a list of all the Error Sets.",
+ "operationId": "listErrorSets",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Error Sets.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorSetList"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/services/errorsets/{errorSetName}": {
+ "get": {
+ "tags": [
+ "ErrorSets"
+ ],
+ "summary": "Get an Error Set.",
+ "operationId": "getErrorSet",
+ "description": "Returns the information for a specific Error Set.",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the requested Error Set.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorSet"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "errorSetName",
+ "description": "The name of the Error Set.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/ResourceName"
+ }
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps/{appName}/published-apis": {
+ "get": {
+ "tags": [
+ "Published APIs"
+ ],
+ "summary": "List Published APIs",
+ "description": "Returns a list of all Published APIs for the specified Environment and App.\n",
+ "operationId": "listPublishedAPIs",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the list of Published APIs for the specified Environment.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPIList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/environmentName"
+ },
+ {
+ "$ref": "#/components/parameters/appName"
+ }
+ ]
+ },
+ "/services/environments/{environmentName}/apps/{appName}/published-apis/{publishedApiName}": {
+ "get": {
+ "tags": [
+ "Published APIs"
+ ],
+ "summary": "Get a Published API",
+ "description": "Gets information about the specified Published API.\n",
+ "operationId": "getPublishedAPI",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved the specified Published API resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Published API resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Published APIs"
+ ],
+ "summary": "Upsert a Published API",
+ "description": "Creates a new Published API or updates an existing Published API resource.",
+ "operationId": "upsertPublishedAPI",
+ "requestBody": {
+ "description": "Defines the Published API to create, or the updates to apply to an existing Published API resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Successfully updated the specified Published API resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Published API resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": "The request to create a Published API succeeded. The resource will be created when the configuration is complete.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Published APIs"
+ ],
+ "summary": "Delete a Published API",
+ "description": "Deletes the specified Published API resource.",
+ "operationId": "deletePublishedAPI",
+ "responses": {
+ "202": {
+ "description": "Published API has been marked for deletion. The resource will be\ndeleted after the publish/cleanup succeeds.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PublishedAPI"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "Successfully deleted the specified Published API resource. No content is returned."
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The specified Published API resource was not found.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/environmentName"
+ },
+ {
+ "$ref": "#/components/parameters/appName"
+ },
+ {
+ "$ref": "#/components/parameters/publishedApiName"
+ }
+ ]
+ },
+ "/security/strategies": {
+ "get": {
+ "tags": [
+ "Strategies"
+ ],
+ "summary": "List all Strategies",
+ "description": "Returns a list of Strategy metadata objects for all of the Strategies.",
+ "operationId": "StrategyServiceList",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Strategies.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StrategyList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Strategies"
+ ],
+ "summary": "Create a Strategy",
+ "operationId": "StrategyServicePost",
+ "description": "Creates a new Strategy resource.\n",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Strategy"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified Strategy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StrategyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/security/strategies/{strategyName}": {
+ "get": {
+ "tags": [
+ "Strategies"
+ ],
+ "summary": "Get a Strategy",
+ "operationId": "StrategyServiceGet",
+ "description": "Returns information for a specific Strategy resource.",
+ "responses": {
+ "200": {
+ "description": "Sucessfully retrieved the requested Strategy.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StrategyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Strategies"
+ ],
+ "summary": "Upsert a Strategy",
+ "operationId": "StrategyServicePut",
+ "description": "Creates a new Strategy or updates an existing Strategy resource.",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Strategy"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Sucessfully updated the specified Strategy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StrategyStatus"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Strategy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/StrategyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Strategies"
+ ],
+ "summary": "Delete a Strategy",
+ "operationId": "StrategyServiceDelete",
+ "description": "Deletes the specified Strategy resource.",
+ "responses": {
+ "204": {
+ "description": "The specified Strategy resource was successfully deleted."
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete the specified Strategy resource failed.\nThe Strategy is referenced by active objects and cannot be deleted. Delete the referencing objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "strategyName",
+ "description": "The name of the Strategy.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/ResourceName"
+ }
+ }
+ ]
+ },
+ "/security/policies": {
+ "get": {
+ "tags": [
+ "Policies"
+ ],
+ "summary": "List all Policies",
+ "description": "Returns a list of Policy metadata objects for all of the Policies.",
+ "operationId": "listPolicies",
+ "responses": {
+ "200": {
+ "description": "Successfully retrieved a list of Policies.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PolicyList"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Policies"
+ ],
+ "summary": "Create a Policy",
+ "operationId": "createPolicy",
+ "description": "Creates a new Policy resource.\n",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Policy"
+ }
+ }
+ }
+ },
+ "responses": {
+ "201": {
+ "description": "Successfully created the specified Policy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PolicyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request failed due to a naming conflict with an existing resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/security/policies/{policyName}": {
+ "get": {
+ "tags": [
+ "Policies"
+ ],
+ "summary": "Get a Policy",
+ "operationId": "getPolicy",
+ "description": "Returns information for a specific Policy resource.",
+ "responses": {
+ "200": {
+ "description": "Sucessfully retrieved the requested Policy.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PolicyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Policies"
+ ],
+ "summary": "Upsert a Policy",
+ "operationId": "updatePolicy",
+ "description": "Creates a new Policy or updates an existing Policy resource.",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Policy"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Sucessfully updated the specified Policy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PolicyStatus"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Successfully created the requested Policy resource.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/PolicyStatus"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad input parameter, or possibly a bad URI. Check the input for typos and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Policies"
+ ],
+ "summary": "Delete a Policy",
+ "operationId": "deletePolicy",
+ "description": "Deletes the specified Policy resource.",
+ "responses": {
+ "204": {
+ "description": "The specified Policy resource was successfully deleted."
+ },
+ "404": {
+ "description": "The resource defined in the URI could not be found. Check the URI for errors and try again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ },
+ "409": {
+ "description": "The request to delete the specified Policy resource failed.\nThe Policy is referenced by active objects and cannot be deleted. Delete the referencing objects or remove the references, then try again.\n",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorModel"
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "policyName",
+ "description": "The name of the Policy.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/ResourceName"
+ }
+ }
+ ]
+ }
+ },
+ "components": {
+ "parameters": {
+ "environmentName": {
+ "name": "environmentName",
+ "description": "The name of the Environment that contains the Component's parent App.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/EnvironmentName"
+ }
+ },
+ "appName": {
+ "name": "appName",
+ "description": "The name of the App that contains the Component resource.",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/AppName"
+ }
+ },
+ "apiDefinitionName": {
+ "name": "apiDefinitionName",
+ "in": "path",
+ "description": "The name of the API Definition resource.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "example": "shopping-app-api-def",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "publishedApiName": {
+ "name": "publishedApiName",
+ "in": "path",
+ "description": "The name of the Published API resource.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "example": "shopping-app-api-staging",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "versionName": {
+ "name": "version",
+ "in": "path",
+ "description": "The Version of the API Definition.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "example": "v1_2fd4e1c6",
+ "schema": {
+ "type": "string"
+ }
+ },
+ "LocationName": {
+ "name": "locationName",
+ "in": "path",
+ "description": "The name of the Location that contains the Instance.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "InstanceName": {
+ "name": "instanceName",
+ "in": "path",
+ "description": "The name of the Instance.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "InstanceGroupName": {
+ "name": "instanceGroupName",
+ "in": "path",
+ "description": "The name of the Instance Group.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "InstanceTemplateName": {
+ "name": "instanceTemplateName",
+ "in": "path",
+ "description": "The name of the Instance Template resource.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "identityProviderName": {
+ "name": "identityProviderName",
+ "in": "path",
+ "description": "The name of the Identity Provider.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "identityProviderClientName": {
+ "name": "identityProviderClientName",
+ "in": "path",
+ "description": "The name of the Identity Provider Client.",
+ "required": true,
+ "style": "simple",
+ "explode": false,
+ "schema": {
+ "type": "string"
+ }
+ },
+ "IntegrationName": {
+ "name": "integrationName",
+ "in": "path",
+ "description": "The name of the Integration resource.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "schemas": {
+ "ResourceName": {
+ "type": "string",
+ "description": "The name of a resource.",
+ "example": "production"
+ },
+ "LocationState": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/OtherLocation"
+ },
+ {
+ "$ref": "#/components/schemas/AWSLocation"
+ },
+ {
+ "$ref": "#/components/schemas/AzureLocation"
+ },
+ {
+ "$ref": "#/components/schemas/VSphereLocation"
+ }
+ ],
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "OTHER_LOCATION": "#/components/schemas/OtherLocation",
+ "AWS_LOCATION": "#/components/schemas/AWSLocation",
+ "AZURE_LOCATION": "#/components/schemas/AzureLocation",
+ "VSPHERE_LOCATION": "#/components/schemas/VSphereLocation"
+ }
+ }
+ },
+ "OtherLocation": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The location type. Select the environment where you want to create the location. \nTo create a location that’s not specific to any cloud environment, select OTHER_LOCATION.\n",
+ "enum": [
+ "OTHER_LOCATION"
+ ]
+ }
+ }
+ },
+ "AWSLocation": {
+ "type": "object",
+ "required": [
+ "vpcID",
+ "region",
+ "integrationRef",
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The location type. Select the environment where you want to create the location. \nTo create a location that’s specific to the AWS cloud environment, select AWS_LOCATION.\n",
+ "enum": [
+ "AWS_LOCATION"
+ ]
+ },
+ "region": {
+ "description": "The AWS region.\n",
+ "type": "string"
+ },
+ "vpcID": {
+ "type": "string",
+ "description": "The vpcID of the AWS Virtual Private Cloud (VPC) where new Instances created under this location should reside.\nThe VPC must be in the specified AWS region.\n"
+ },
+ "integrationRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ },
+ "AzureLocation": {
+ "type": "object",
+ "required": [
+ "type",
+ "region",
+ "resourceGroup",
+ "subscriptionID",
+ "integrationRef"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The location type.",
+ "enum": [
+ "AZURE_LOCATION"
+ ]
+ },
+ "region": {
+ "description": "The Azure region.",
+ "type": "string"
+ },
+ "resourceGroup": {
+ "type": "string",
+ "description": "The name of the resourceGroup."
+ },
+ "subscriptionID": {
+ "type": "string",
+ "description": "The unique alphanumeric string that identifies the Azure subscription."
+ },
+ "integrationRef": {
+ "description": "Integration ref.",
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ },
+ "VSphereLocation": {
+ "type": "object",
+ "required": [
+ "type",
+ "datacenter",
+ "integrationRef"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The location type.",
+ "enum": [
+ "VSPHERE_LOCATION"
+ ]
+ },
+ "datacenter": {
+ "description": "A VSphere data center.",
+ "type": "string"
+ },
+ "folder": {
+ "type": "string",
+ "description": "The name of the VM folder that you want to add your instance to. If no name is provided, the instance will be created in the folder containing the VM template your instance is cloned from."
+ },
+ "integrationRef": {
+ "description": "Integration ref.",
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ },
+ "Location": {
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/LocationState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/LocationState"
+ }
+ }
+ },
+ "GetLocationResponse": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/Location"
+ }
+ ]
+ },
+ "ListLocationResponse": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Location"
+ }
+ }
+ }
+ },
+ "AppList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/App"
+ }
+ }
+ }
+ },
+ "App": {
+ "type": "object",
+ "description": "An App is a collection of Components.",
+ "required": [
+ "metadata"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "x-f5-experimental": true,
+ "type": "object"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/AppCurrentStatus"
+ }
+ }
+ },
+ "AppCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "componentRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ }
+ },
+ "Component": {
+ "description": "A component represents the processing –- reverse proxying, rate limiting, security policy enforcement, header rewrites, etc.\n–- of traffic associated with a logical part (for example, microservice) of an application/API. It also defines the subsequent\nload balancing of traffic to workloads implementing that part of the application/API.\n\nA component can be either a web or a TCP/UDP component –- indicated by the component type. Web components are used to\nconfigure NGINX functionality associated with HTTP/HTTPS protocols and inherit web and common settings from linked Gateways.\nTCP/UDP components are used to configure NGINX functionality associated with TCP/UDP protocols\nand inherit TCP/UDP and common settings from linked Gateways.\n",
+ "type": "object",
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/ComponentDesiredState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/ComponentCurrentStatus"
+ }
+ }
+ },
+ "ComponentName": {
+ "type": "string"
+ },
+ "ComponentList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Component"
+ }
+ }
+ }
+ },
+ "WorkloadGroupSnippet": {
+ "description": "The NGINX directives to apply to the upstream blocks generated by the workload groups\nin the backend. Directives are applied to all workload groups by default. Use\napplicableWorkloadGroups to apply directives only to specific workload groups.\n",
+ "allOf": [
+ {
+ "type": "object",
+ "properties": {
+ "applicableWorkloadGroups": {
+ "type": "array",
+ "description": "Workload group name.",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ {
+ "$ref": "#/components/schemas/NginxConfig"
+ }
+ ]
+ },
+ "ComponentConfigSnippets": {
+ "type": "object",
+ "description": "The NGINX config snippets to insert into the server and location blocks\ngenerated by the component URIs.\n\n**Caution**: When you use snippets to customize your NGINX configuration, your changes are\napplied to the nginx.conf file *as is*. NGINX Controller does not verify that your configuration\nis valid before applying the snippet.\n\nWe strongly recommend verifying snippets in a lab environment before making any changes\nin production.\n",
+ "properties": {
+ "uriSnippets": {
+ "description": "An array of URI snippets.\n",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UriSnippet"
+ }
+ },
+ "workloadGroupSnippets": {
+ "description": "An array of workload group snippets.\n",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WorkloadGroupSnippet"
+ }
+ }
+ }
+ },
+ "ComponentStateCommon": {
+ "type": "object",
+ "description": "Settings common to Web & TCP/UDP Components.",
+ "properties": {
+ "configSnippets": {
+ "$ref": "#/components/schemas/ComponentConfigSnippets"
+ }
+ }
+ },
+ "ComponentCurrentStatus": {
+ "description": "The current snapshot of the component settings that are reflected in the configuration on NGINX instances associated with\nthe Gateways that this Component references.\n\nThese settings should converge to those in Desired State as the new configuration is applied unless there are issues;\nthe State setting gives a summary of how the convergence is proceeding.\n",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ComponentWebCurrentStatus"
+ },
+ {
+ "$ref": "#/components/schemas/ComponentTcpUdpCurrentStatus"
+ }
+ ]
+ },
+ "ComponentWebCurrentStatus": {
+ "description": "The current snapshot of the web component settings that are reflected in the configuration on NGINX instances associated with\nthe Gateways that this component references.\n\nThese settings should converge to those in Desired State as the new configuration is applied unless there are issues;\nthe State setting gives a summary of how the convergence is proceeding.\n",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentStateCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "componentType": {
+ "description": "Defines what type of Component this is.",
+ "type": "string",
+ "enum": [
+ "WEB"
+ ]
+ },
+ "ingress": {
+ "$ref": "#/components/schemas/ComponentWebIngress"
+ },
+ "backend": {
+ "$ref": "#/components/schemas/WebBackend"
+ },
+ "programmability": {
+ "$ref": "#/components/schemas/Programmability"
+ },
+ "logging": {
+ "$ref": "#/components/schemas/Logging"
+ },
+ "security": {
+ "$ref": "#/components/schemas/Security"
+ },
+ "errorSetRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "compression": {
+ "$ref": "#/components/schemas/Compression"
+ },
+ "caching": {
+ "$ref": "#/components/schemas/Caching"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ }
+ }
+ }
+ ]
+ },
+ "ComponentTcpUdpCurrentStatus": {
+ "description": "The current snapshot of the TCP/UDP component settings that are reflected in the configuration on NGINX instances associated with\nthe Gateways that this component references.\n\nThese settings should converge to those in Desired State as the new configuration is applied unless there are issues;\nthe State setting gives a summary of how the convergence is proceeding.\n",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentStateCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "componentType": {
+ "description": "Defines what type of Component this is.",
+ "type": "string",
+ "enum": [
+ "TCPUDP"
+ ]
+ },
+ "ingress": {
+ "$ref": "#/components/schemas/ComponentTcpUdpIngress"
+ },
+ "backend": {
+ "$ref": "#/components/schemas/TcpUdpBackend"
+ },
+ "logging": {
+ "$ref": "#/components/schemas/Logging"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ }
+ }
+ }
+ ]
+ },
+ "GatewayName": {
+ "type": "string"
+ },
+ "GatewayList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Gateway"
+ }
+ }
+ }
+ },
+ "GatewayCurrentStatus": {
+ "description": "The current snapshot of the gateway settings that are reflected in the configuration on NGINX instances referenced by this Gateway.\nThese settings should converge to those in Desired State as the new configuration is applied unless there are issues;\nthe State setting gives a summary of how the convergence is proceeding.\n",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/GatewayWebState"
+ },
+ {
+ "$ref": "#/components/schemas/GatewayStateCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "ingress": {
+ "$ref": "#/components/schemas/GatewayIngress"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ }
+ }
+ }
+ ]
+ },
+ "Gateway": {
+ "type": "object",
+ "description": "A Gateway represents the initial network entry point of application and/or API traffic into an NGINX instance that is\nin the data path of this traffic. Gateway settings are combined with Component settings that reference the Gateway;\nthe resulting composite config is sent to the NGINX instances that the Gateway references.\n\nA Gateway can be referenced by either web components and/or TCP/UDP components. Web-only settings in the Gateway (for example, web URIs)\napply only to web components. TCP/UDP-only settings in the Gateway (for example, TCP/UDP URIs) apply only to TCP/UDP components.\nWeb and TCP/UDP common settings in the Gateway (for example, global TLS, socket) apply to both web and TCP/UDP components.\n\nExamples:\nGateway with web and TCP/UDP URIs, web-specific settings, common settings. Web URIs and web settings apply to web components.\nCommon settings apply to both component types. TCP/UDP URIs apply only to TCP/UDP components –- presently, there are no other TCP/UDP only settings.\n\nGateway web URIs (for example, https://www.xyz.com) combined with web component URIs (for example, /blog) define web URI config (https://www.xyz.com/blog).\nComponent TCP/UDP URIs define TCP/UDP URI config (for example, tcp+tls://192.168.1.1:200); Gateway TCP/UDP URIs can provide TLS info plus restrict\nwhich TCP/UDP URIs can be in the component. Alternatively, component URIs fully define the URI config if the Gateway has no URIs.\n\nIf only a single URI type is in the Gateway, the URI config for that type is determined by combining the Gateway URIs with\nthe URIs from components of that type; only component URIs are used for the URI config for the other type.\n\nFor HTTPS URIs, global Gateway TLS settings are used when more specific TLS info is not present in the Gateway URIs,\nor for component URIs that have an HTTPS protocol and hostnames with no specific URI or component global TLS settings defined.\n\nFor tcp+tls URIs, Gateway TLS settings are used when TLS info is not defined in a component URI or component global TLS.\nA Gateway URI’s TLS info is used if it encompasses the component URI. For example, tcp+tls://192.168.1.5:100-104 in the Gateway and\ncomponent URI of tcp+tls://192.168.1.5:100. Global Gateway TLS is used if no other TLS settings apply.\n",
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/GatewayDesiredState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/GatewayCurrentStatus"
+ }
+ }
+ },
+ "GZip": {
+ "properties": {
+ "isEnabled": {
+ "type": "boolean",
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip"
+ }
+ },
+ "buffers": {
+ "type": "object",
+ "properties": {
+ "number": {
+ "type": "integer"
+ },
+ "size": {
+ "type": "string",
+ "pattern": "^[0-9]+[k|K|m|M]{1}$"
+ }
+ },
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_buffers"
+ }
+ },
+ "level": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 9,
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_comp_level"
+ }
+ },
+ "disabledUserAgents": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true,
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_disable"
+ }
+ },
+ "httpVersion": {
+ "type": "string",
+ "pattern": "^[1-3]{1}\\.[0-1]{1}$",
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_http_version"
+ }
+ },
+ "minLength": {
+ "type": "integer",
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_min_length"
+ }
+ },
+ "proxied": {
+ "type": "string",
+ "enum": [
+ "DISABLED",
+ "EXPIRED",
+ "NOCACHE",
+ "NOSTORE",
+ "PRIVATE",
+ "NOLASTMODIFIED",
+ "NOETAG",
+ "AUTH",
+ "ANY"
+ ],
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_proxied"
+ }
+ },
+ "mimeTypes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "uniqueItems": true,
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types"
+ }
+ },
+ "vary": {
+ "type": "string",
+ "enum": [
+ "DISABLED",
+ "ENABLED"
+ ],
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_vary"
+ }
+ },
+ "static": {
+ "type": "string",
+ "enum": [
+ "DISABLED",
+ "ENABLED",
+ "ALWAYS"
+ ],
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html#gzip_static"
+ }
+ }
+ }
+ },
+ "Compression": {
+ "description": "Gzip compression settings.",
+ "type": "object",
+ "properties": {
+ "gzip": {
+ "$ref": "#/components/schemas/GZip"
+ }
+ }
+ },
+ "GatewayWebState": {
+ "description": "Non-ingress settings in a Gateway that apply only to Web Components.",
+ "type": "object",
+ "properties": {
+ "errorSetRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "compression": {
+ "$ref": "#/components/schemas/Compression"
+ }
+ }
+ },
+ "NginxDirective": {
+ "required": [
+ "directive"
+ ],
+ "properties": {
+ "directive": {
+ "type": "string",
+ "description": "The name of the NGINX directive. For a list of NGINX Directives, refer to [the NGINX documentation](http://nginx.org/en/docs/dirindex.html).\n"
+ },
+ "args": {
+ "type": "array",
+ "description": "Directive arguments.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "block": {
+ "type": "array",
+ "description": "The directives to include within a block directive or context.",
+ "items": {
+ "$ref": "#/components/schemas/NginxDirective"
+ }
+ }
+ }
+ },
+ "NginxConfig": {
+ "type": "object",
+ "required": [
+ "directives"
+ ],
+ "properties": {
+ "directives": {
+ "type": "array",
+ "description": "List of NGINX directives to add to the configuration.\n",
+ "items": {
+ "$ref": "#/components/schemas/NginxDirective"
+ }
+ }
+ }
+ },
+ "URIMatchMethod": {
+ "description": "Specifies how to determine a match between an incoming Web URI and configured Web URI.",
+ "type": "string",
+ "enum": [
+ "PREFIX",
+ "REGEX",
+ "REGEX_CASE_SENSITIVE",
+ "SUFFIX",
+ "EXACT"
+ ],
+ "default": "PREFIX"
+ },
+ "ApplicableUri": {
+ "type": "object",
+ "required": [
+ "uri"
+ ],
+ "properties": {
+ "uri": {
+ "type": "string"
+ },
+ "matchMethod": {
+ "$ref": "#/components/schemas/URIMatchMethod"
+ }
+ }
+ },
+ "ApplicableUris": {
+ "type": "array",
+ "description": "Defines an array of ingress URIs with a corresponding matchMethod that this rule/snippet applies to.\nBy default, a rule/snippet applies to all ingress URIs in the gateway/component. A snippet can be\napplied only to URIs of the gateway/component that it is in. A snippet in a component cannot be\napplied to the gateway URI. However, a rule can be applied at a gateway level by specifying ingress\nURIs from the gateway, for example, \"http://www.nginx.com\". Note that applying the rule to URIs at\na gateway level can affect other components. The URI and the matchMethod must match an ingress URI defined\neither at the component or gateway level. If no match is found, the request is rejected.\n",
+ "items": {
+ "$ref": "#/components/schemas/ApplicableUri"
+ }
+ },
+ "UriSnippet": {
+ "description": "The NGINX directives to apply to the server and location blocks generated by the URIs.\nDirectives are applied to all URIs by default. Use applicableURIs to apply directives\nonly to specific URIs.\n",
+ "allOf": [
+ {
+ "type": "object",
+ "properties": {
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ }
+ }
+ },
+ {
+ "$ref": "#/components/schemas/NginxConfig"
+ }
+ ]
+ },
+ "DiskStore": {
+ "type": "object",
+ "required": [
+ "path",
+ "maxSize",
+ "minFree",
+ "inMemoryStoreSize"
+ ],
+ "properties": {
+ "path": {
+ "description": "Defines what the path is for this storage",
+ "example": "/tmp/hdd1",
+ "type": "string",
+ "minLength": 1
+ },
+ "isDefault": {
+ "description": "When more than one disk stores are specified, the data stored in the cache is split by percentage or string.\n`isDefault` specifies a default storage for cache data that does not meet the percent or string criteria.\n",
+ "type": "boolean",
+ "default": false
+ },
+ "percentCriteria": {
+ "description": "Defines the percentage that should be allocated to this store. This must be specified when `criteriaType` is PERCENTAGE.",
+ "type": "string",
+ "example": "75%",
+ "pattern": "\\d+(?:\\.\\d+)?%"
+ },
+ "stringCriteria": {
+ "description": "Defines string pattern of data that should go in to this store. This must be specified when `criteriaType` is STRING",
+ "type": "array",
+ "items": {
+ "description": "Depending on the 'SplitConfig' \"Key\", string could have different patterns.\nLike ~.mp3$ for REGEX match or any string like 'hostname.*' or IP address\n",
+ "type": "string",
+ "minLength": 1,
+ "example": "[\"~.mp3$\", \"~*.avi\"],[\"10.1.1.1\", \"10.1.1.2\"]"
+ }
+ },
+ "maxSize": {
+ "type": "string",
+ "description": "Defines the maximum size that the cache can grow to",
+ "example": "5G",
+ "pattern": "^[0-9]+[kKmMgG]?$"
+ },
+ "minFree": {
+ "type": "string",
+ "description": "Defines the minimum amount of free disk space on the drive for the cache. If the free disk space drops below the minimum value, the cache is trimmed.",
+ "example": "10k",
+ "pattern": "^[0-9]+[kKmMgG]?$"
+ },
+ "inMemoryStoreSize": {
+ "type": "string",
+ "description": "Defines the size of the memory zone where information about the data is stored.",
+ "example": "500m",
+ "pattern": "^[0-9]+[kKmM]?$"
+ },
+ "trimPolicy": {
+ "description": "Defines how we configure `manager_files` for the proxy_cache_path\nCache management is performed in iterations. During one iteration no more than `maxFiles` items are deleted\nThis policy defines how many files are deleted, how often and how long the process lasts.\n",
+ "type": "object",
+ "properties": {
+ "maxFiles": {
+ "type": "integer",
+ "description": "Defines how many files are deleted in one iteration. NGINX defaults this to 100",
+ "minimum": 1
+ },
+ "frequency": {
+ "type": "string",
+ "description": "Defines the length of the pause between cache management iterations. The default for NGINX is 50 milliseconds.",
+ "example": "2s",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ },
+ "durationThreshold": {
+ "type": "string",
+ "description": "Defines the duration for one cache management iteration. The default for NGINX is 200 milliseconds.",
+ "example": "2s",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ }
+ }
+ },
+ "loaderPolicy": {
+ "description": "Defines how `loader_files` are configured for the `proxy_cache_path`.\nloading is done in iterations. During one iteration no more than maxFiles items are loaded\nDefines how previosly cached data is loadded in the cache `Zone`.\n",
+ "type": "object",
+ "properties": {
+ "maxFiles": {
+ "type": "integer",
+ "description": "During one iteration no more than `files` items are loaded. NGINX defaults this to 100",
+ "minimum": 1
+ },
+ "frequency": {
+ "type": "string",
+ "description": "Defines the length of the pause between cache management iterations. For NGINX, the default is 50 milliseconds.",
+ "example": "2s",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ },
+ "durationThreshold": {
+ "type": "string",
+ "description": "Defines the maximum duration for one cache management iteration. For NGINX, the default is 200 milliseconds.",
+ "example": "2s",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ }
+ }
+ },
+ "purgerPolicy": {
+ "description": "Defines how we configure `purger` for the proxy_cache_path\nPurger is done in iterations. During one iteration no more than maxFiles items are scanned\nSpecifies whether cache entires matching a wildcard key are removed from the disk by the cache purger.\n",
+ "type": "object",
+ "properties": {
+ "maxFiles": {
+ "type": "integer",
+ "description": "Defines the number of items to scan during one iteration. For NGINX, default is 10 items.",
+ "minimum": 1
+ },
+ "frequency": {
+ "type": "string",
+ "description": "Defines the length of the pause between cache purge iterations. For NGINX, the default is 50 milliseconds.",
+ "example": "10ms",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ },
+ "durationThreshold": {
+ "type": "string",
+ "description": "Defines the maximum duration for one cache purge iteration. For NGINX, the default is 50 milliseconds.",
+ "example": "10ms",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ }
+ }
+ },
+ "directoryLevel": {
+ "type": "object",
+ "description": "Defines the level of the directory structure that NGINX creates for the cache.\nDefines the cache hierarchy levels from 1 to 3, with each level accepting a value of `1` or `2`.\nFor example, `levels=1:2` file names in a cache will look like this. (**Note**: `/c/29` & `29c` at end)\n/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c\n",
+ "properties": {
+ "first": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 2
+ },
+ "mid": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 2
+ },
+ "last": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 2
+ }
+ }
+ },
+ "tempPath": {
+ "description": "Determines whether you'll use a temporary path for the cache disk store.\nYou can define the path location by using `proxy_temp_path` in a `configSnippet` for the Component.\n",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ]
+ },
+ "inactiveTime": {
+ "description": "Defines the length of time to wait before removing cached data that haven't been accessed.",
+ "example": "5s",
+ "type": "string",
+ "pattern": "^[0-9]+[h|hm|hms|ms|m|s]{1,2}$"
+ }
+ }
+ },
+ "Caching": {
+ "description": "Cache settings for components applicable to web client requests.",
+ "type": "object",
+ "required": [
+ "diskStores"
+ ],
+ "properties": {
+ "splitConfig": {
+ "description": "Allows the cache to be split among multiple storage devices",
+ "type": "object",
+ "required": [
+ "criteriaType"
+ ],
+ "properties": {
+ "key": {
+ "type": "string",
+ "description": "Defines the variable on which the cache is split across different storage devices.",
+ "example": "${remote_addr}${http_user_agent}${date_gmt}",
+ "minLength": 1
+ },
+ "criteriaType": {
+ "type": "string",
+ "description": "Defines the criteria on which the cache is split across different storage devices.",
+ "enum": [
+ "PERCENTAGE",
+ "STRING"
+ ],
+ "default": "PERCENTAGE"
+ }
+ }
+ },
+ "diskStores": {
+ "description": "Defines an array of disk stores. If more than one is specified, the cache contents are split between the stores using splitConfig settings.\nIf criteriaType is PERCENTAGE, then percentCriteria should be specified to control how much goes in to a particular store.\nIf the criteriaType is STRING, then stringCriteria should be specified to control the split based on a pattern match.\n",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DiskStore"
+ }
+ }
+ }
+ },
+ "ComponentWebDesiredState": {
+ "description": "The desired settings in the Web Component that the user wants in the configuration on NGINX instances associated with\nthe Gateways which this component references.\n",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentStateCommon"
+ },
+ {
+ "type": "object",
+ "required": [
+ "ingress",
+ "backend"
+ ],
+ "properties": {
+ "componentType": {
+ "description": "Defines the Component type. The default type is Web.",
+ "type": "string",
+ "enum": [
+ "WEB"
+ ]
+ },
+ "ingress": {
+ "$ref": "#/components/schemas/ComponentWebIngress"
+ },
+ "backend": {
+ "$ref": "#/components/schemas/WebBackend"
+ },
+ "programmability": {
+ "$ref": "#/components/schemas/Programmability"
+ },
+ "logging": {
+ "$ref": "#/components/schemas/Logging"
+ },
+ "security": {
+ "$ref": "#/components/schemas/Security"
+ },
+ "errorSetRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "compression": {
+ "$ref": "#/components/schemas/Compression"
+ },
+ "caching": {
+ "$ref": "#/components/schemas/Caching"
+ }
+ }
+ }
+ ]
+ },
+ "ComponentTcpUdpIngress": {
+ "description": "Ingress settings in a TCP/UDP Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentIngressCommon"
+ }
+ ]
+ },
+ "TcpUdpMonitoring": {
+ "description": "Health monitor settings across all workload groups in a TCP/UDP Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/MonitoringCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "send": {
+ "description": "Probe request for a TCP/UDP monitor.",
+ "type": "string"
+ },
+ "response": {
+ "description": "Case-sensitive regular expression for the expected success response to a TCP/UDP monitor.",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ },
+ "TcpUdpProxy": {
+ "description": "Proxy retry and timeout settings applicable to servers in a TcpUdp workloadGroup associated with a Component.",
+ "type": "object",
+ "properties": {
+ "nextUpstream": {
+ "description": "When a connection to the proxied server cannot be established, determines whether a client connection will be passed to the next server.",
+ "type": "string",
+ "enum": [
+ "ON",
+ "OFF"
+ ],
+ "default": "OFF"
+ },
+ "connectTimeout": {
+ "description": "Defines a timeout for establishing a connection with the proxied server.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$"
+ },
+ "proxyTimeout": {
+ "description": "Sets the timeout between two successive read or write operations on client or proxied server connections.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$"
+ }
+ }
+ },
+ "TcpUdpWorkloadGroup": {
+ "description": "Group of servers hosting a part of a TCP/UDP application represented by a Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/WorkloadGroupCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "proxy": {
+ "$ref": "#/components/schemas/TcpUdpProxy"
+ },
+ "useServerPort": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "uris": {
+ "type": "object",
+ "description": "The URI of a server that hosts a TCP/UDP application.\n\nThe URI must conform to the format `schema://address:port`.\n\n- The schema must be one of the following: `tcp`, `udp`, or `tcp+tls`.\n- The address value can be an IP address or a host name.\n- All three elements -- schema, address, and port -- are required.\n\nNote: When `useServerPort` is `ENABLED`, then you should define a single URI that uses the `schema://address` format.\nDefining a `port` value for the URI when also using `useServerPort` will result in an error.\n\nFor example:\n\n- `tcp://192.0.2.247:8443`\n- `tcp+tls://192.0.2.247:8449`\n- `udp://www.f5workload.com:989`\n",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/WorkloadUri"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "TcpUdpBackend": {
+ "description": "Backend settings in a TCP/UDP Component.\n",
+ "type": "object",
+ "properties": {
+ "monitoring": {
+ "$ref": "#/components/schemas/TcpUdpMonitoring"
+ },
+ "workloadGroups": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/TcpUdpWorkloadGroup"
+ }
+ }
+ }
+ },
+ "ComponentTcpUdpDesiredState": {
+ "description": "The desired settings in the TCP/UDP Component to use in the configuration on NGINX instances associated with the Gateways that this Component references.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentStateCommon"
+ },
+ {
+ "type": "object",
+ "required": [
+ "componentType",
+ "ingress",
+ "backend"
+ ],
+ "properties": {
+ "componentType": {
+ "description": "Defines what type of Component this is. The type must be TCPUDP.",
+ "type": "string",
+ "enum": [
+ "TCPUDP"
+ ]
+ },
+ "ingress": {
+ "$ref": "#/components/schemas/ComponentTcpUdpIngress"
+ },
+ "backend": {
+ "$ref": "#/components/schemas/TcpUdpBackend"
+ },
+ "logging": {
+ "$ref": "#/components/schemas/Logging"
+ }
+ }
+ }
+ ]
+ },
+ "ComponentDesiredState": {
+ "description": "The desired component settings to use in the NGINX instance configuration that's associated with\nthe Gateways that this component references.\n",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ComponentWebDesiredState"
+ },
+ {
+ "$ref": "#/components/schemas/ComponentTcpUdpDesiredState"
+ }
+ ]
+ },
+ "GatewayConfigSnippets": {
+ "type": "object",
+ "description": "The NGINX config snippets to insert into the NGINX config generated by the gateway.\nNote that the default directives and directives generated by the native parts of the\nAPI(API sections other than configSnippets) cannot be overriden.\nmainSnippet - Insert directives in the main context.\nhttpSnippet - Insert directives in the http context.\nstreamSnippet - Insert directives in the stream context.\nuriSnippet - Insert into server blocks generated by the gateway URIs.\n This applies only to HTTP URIs, since TCP and UDP URIs do not\n generate server blocks.\n\n**Caution**: When you use snippets to customize your NGINX configuration, your changes are\napplied to the nginx.conf file *as is*. NGINX Controller does not verify that your configuration\nis valid before applying the snippet.\n\nWe strongly recommend verifying snippets in a lab environment before making any changes\nin production.\n",
+ "properties": {
+ "mainSnippet": {
+ "$ref": "#/components/schemas/NginxConfig"
+ },
+ "httpSnippet": {
+ "$ref": "#/components/schemas/NginxConfig"
+ },
+ "streamSnippet": {
+ "$ref": "#/components/schemas/NginxConfig"
+ },
+ "uriSnippets": {
+ "description": "An array of URI snippets.\n",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UriSnippet"
+ }
+ }
+ }
+ },
+ "HA": {
+ "description": "Data path high availability settings",
+ "type": "object",
+ "properties": {
+ "isEnabled": {
+ "type": "boolean",
+ "description": "Enables or disables HA.\n\nWhen set to `true`, supports configuring instances in an active‑passive, high‑availability (HA) setup.\n\nTo configure the gateway on HA mode:\n - `keepalived` must be installed and configured on the desired instances.\n - At least one listen IP address must be specified in the `listenIps` section within `InstanceRefs`\n\n See the `listenIps` section for additional requirements for configuring HA.\n"
+ }
+ }
+ },
+ "GatewayStateCommon": {
+ "description": "Non-ingress settings in a Gateway that apply to Web and TCP/UDP Components.",
+ "type": "object",
+ "properties": {
+ "configSnippets": {
+ "$ref": "#/components/schemas/GatewayConfigSnippets"
+ },
+ "ha": {
+ "$ref": "#/components/schemas/HA"
+ }
+ }
+ },
+ "ServiceConfigState": {
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "default": "DISABLED"
+ },
+ "GatewaySocketSettings": {
+ "description": "Socket settings in a Gateway.",
+ "type": "object",
+ "properties": {
+ "setFib": {
+ "x-f5-experimental": true,
+ "type": "integer"
+ },
+ "fastOpen": {
+ "x-f5-experimental": true,
+ "type": "integer"
+ },
+ "acceptFilter": {
+ "x-f5-experimental": true,
+ "type": "string",
+ "enum": [
+ "DATA_READY",
+ "HTTP_READY"
+ ]
+ },
+ "deferred": {
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "backlog": {
+ "x-f5-experimental": true,
+ "type": "integer",
+ "default": -1
+ },
+ "isIpv6Only": {
+ "x-f5-experimental": true,
+ "type": "boolean",
+ "default": false
+ },
+ "reusePort": {
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "tcpKeepAlive": {
+ "type": "object",
+ "properties": {
+ "state": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "idle": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$"
+ },
+ "interval": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$"
+ },
+ "count": {
+ "type": "integer"
+ }
+ }
+ },
+ "receiveBufferSize": {
+ "type": "string",
+ "pattern": "^[0-9]+[k|K|m|M]{1}$"
+ },
+ "sendBufferSize": {
+ "type": "string",
+ "pattern": "^[0-9]+[k|K|m|M]{1}$"
+ }
+ }
+ },
+ "TLS": {
+ "description": "TLS settings applicable to URIs.",
+ "type": "object",
+ "required": [
+ "certRef"
+ ],
+ "properties": {
+ "certRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "protocols": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "TLSv1|TLSv1\\.[1-3]|SSLv2|SSLv3"
+ }
+ },
+ "cipher": {
+ "type": "string",
+ "example": "ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;"
+ },
+ "preferServerCipher": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "sessionCache": {
+ "type": "string",
+ "enum": [
+ "OFF",
+ "NONE",
+ "BUILTIN",
+ "SHARED"
+ ],
+ "default": "OFF"
+ }
+ }
+ },
+ "IngressUri": {
+ "type": "object",
+ "properties": {
+ "matchMethod": {
+ "$ref": "#/components/schemas/URIMatchMethod"
+ },
+ "tls": {
+ "$ref": "#/components/schemas/TLS"
+ },
+ "serverPoolPort": {
+ "description": "The port number used when the IngressUri is deployed to an Instance that's a member of a BIG-IP server pool.",
+ "type": "integer"
+ }
+ }
+ },
+ "IngressUris": {
+ "type": "object",
+ "description": "Defines the URI in Gateways and Components. The URI has different requirements depending on where it is used.\n\nFor Web URIs in Gateways, `uris` must be a complete URI that follows the format `://host[:port]`;\nadditionally each URI can have a match method specified and an HTTPS URI can include TLS information.\n Examples:\n - `http://www.f5.com`\n - `https://www.f5.com`\n - `http://www.f5.com:8080`\n - `http://*.info.f5.com`\n\nFor Web URIs in Components, `uris` can be either a complete URI that follows the format `://host[:port][/path]`\nor a relative path that follows the format `/path[/...]`;\nadditionally each URI can have a match method specified and an HTTPS URI can include TLS information.\n Examples:\n - `/images`\n - `/*.jpg`\n - `/locations/us/wa*`\n - `http://www.f5.com:8080/sales`\n - `http://*.f5.com:5050/testing`\n\nFor TCP/UDP URIs in Gateways and Components,`uris` must be a complete URI that follows the format `://<*|IP>:`;\nadditionally a tcp+tls URI can include TLS information. Match method is not applicable to TCP/UDP URIs.\n Examples:\n - `tcp://192.168.1.1:12345`\n - `tcp+tls://192.168.1.1:12346`\n - `tcp://192.168.1.1:12345-12350`\n - `tcp://*:12345`\n - `udp://192.168.1.1:12345`\n - `udp://*:12345`\n\nIn a TCP/UDP Component, URIs can either all have a protocol of udp or a mix of TCP and tcp+tls.\n",
+ "additionalProperties": {
+ "description": "Provide the URI associated with the resource.",
+ "$ref": "#/components/schemas/IngressUri"
+ }
+ },
+ "ComponentIngressCommon": {
+ "description": "Ingress settings common to Web and TCP/UDP components.",
+ "type": "object",
+ "required": [
+ "uris"
+ ],
+ "properties": {
+ "uris": {
+ "$ref": "#/components/schemas/IngressUris"
+ },
+ "gatewayRefs": {
+ "description": "Reference(s) to existing Gateway resource(s).",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "tls": {
+ "$ref": "#/components/schemas/TLS"
+ }
+ }
+ },
+ "ComponentWebIngressClient": {
+ "description": "Non-buffer settings in a Component applicable to Web client requests.",
+ "type": "object",
+ "properties": {
+ "bodyInFileOnly": {
+ "description": "Determines whether NGINX Controller should save the entire client request body into a file.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED",
+ "CLEAN"
+ ],
+ "default": "DISABLED",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_file_only"
+ }
+ },
+ "bodyTimeout": {
+ "description": "Defines a timeout for reading the client request body.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout"
+ }
+ },
+ "maxBodySize": {
+ "description": "Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field.\n\nDisables checking of client request body size when set to 0.\n",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size"
+ }
+ }
+ }
+ },
+ "ComponentWebIngress": {
+ "description": "Ingress settings in a Web Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ComponentIngressCommon"
+ },
+ {
+ "$ref": "#/components/schemas/WebIngressCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "client": {
+ "$ref": "#/components/schemas/ComponentWebIngressClient"
+ },
+ "buffers": {
+ "$ref": "#/components/schemas/WebIngressBuffersCommon"
+ }
+ }
+ }
+ ]
+ },
+ "MonitoringCommon": {
+ "description": "Monitor settings common to Web and TCP/UDP.",
+ "type": "object",
+ "properties": {
+ "defaultState": {
+ "type": "string",
+ "enum": [
+ "HEALTHY",
+ "UNHEALTHY"
+ ],
+ "default": "HEALTHY"
+ },
+ "interval": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 5
+ },
+ "consecutiveSuccessThreshold": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "consecutiveFailureThreshold": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "port": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 65535
+ },
+ "healthEvents": {
+ "description": "When enabled, the NGINX Controller Agent generates events related to the\nhealth of the workload group members. Two types of events are generated:\n- An event when the health status of a workload group member changes.\n- A periodic event per component with the health status of all workload groups.\n",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "default": "DISABLED"
+ }
+ }
+ },
+ "MonitorAddHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName",
+ "headerValue"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Adds monitor header details.",
+ "enum": [
+ "ADD"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the monitor header to modify.",
+ "minLength": 1
+ },
+ "headerValue": {
+ "type": "string",
+ "description": "The value to apply to the monitor header.",
+ "minLength": 1
+ }
+ }
+ },
+ "MonitorDeleteHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Deletes monitor header details.",
+ "enum": [
+ "DELETE"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the monitor header to modify.",
+ "minLength": 1
+ }
+ }
+ },
+ "MonitorHeaderModification": {
+ "type": "object",
+ "discriminator": {
+ "propertyName": "action",
+ "mapping": {
+ "ADD": "#/components/schemas/MonitorAddHeader",
+ "DELETE": "#/components/schemas/MonitorDeleteHeader"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/MonitorAddHeader"
+ },
+ {
+ "$ref": "#/components/schemas/MonitorDeleteHeader"
+ }
+ ]
+ },
+ "MonitorResponseStatus": {
+ "type": "object",
+ "properties": {
+ "range": {
+ "type": "object",
+ "properties": {
+ "startCode": {
+ "type": "integer",
+ "minimum": 100,
+ "maximum": 599
+ },
+ "endCode": {
+ "type": "integer",
+ "minimum": 100,
+ "maximum": 599
+ }
+ }
+ },
+ "codes": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "minimum": 100,
+ "maximum": 599
+ }
+ },
+ "match": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "MonitorResponseContent": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "type": "string"
+ },
+ "match": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "WebMonitorResponse": {
+ "description": "Settings that define successful responses to a Web monitor.",
+ "type": "object",
+ "properties": {
+ "status": {
+ "$ref": "#/components/schemas/MonitorResponseStatus"
+ },
+ "headers": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/MonitorResponseContent"
+ }
+ },
+ "body": {
+ "$ref": "#/components/schemas/MonitorResponseContent"
+ }
+ }
+ },
+ "WebMonitoring": {
+ "description": "Health monitor settings across all workload groups in a Web Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/MonitoringCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "uri": {
+ "description": "URI containing the relative path that the monitor probe is sent to; the host is specified in the URI in the workload group.",
+ "type": "string",
+ "default": "/"
+ },
+ "headerModifications": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MonitorHeaderModification"
+ }
+ },
+ "response": {
+ "description": "Settings that define successful responses to a Web monitor.",
+ "$ref": "#/components/schemas/WebMonitorResponse"
+ }
+ }
+ }
+ ]
+ },
+ "RoundRobinLB": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "ROUND_ROBIN"
+ ]
+ }
+ }
+ },
+ "IPHashLB": {
+ "type": "object",
+ "description": "IP Hash Load Balancing only applicable to Web Components.",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "IPHASH"
+ ]
+ }
+ }
+ },
+ "LeastConnLB": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "LEAST_CONNECTIONS"
+ ]
+ }
+ }
+ },
+ "HashLBMethod": {
+ "type": "object",
+ "required": [
+ "type",
+ "userKey"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "HASH"
+ ]
+ },
+ "userKey": {
+ "type": "string"
+ },
+ "consistentHash": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ }
+ }
+ },
+ "LeastTimeLBMethod": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "LEAST_TIME"
+ ]
+ },
+ "latencyParameter": {
+ "type": "string",
+ "description": "Values applicable to a Web Component are: [HEADER, LAST_BYTE, LAST_BYTE_INFLIGHT];\nValues applicable to a TCP/UDP Component are: [CONNECT, FIRST_BYTE, LAST_BYTE, LAST_BYTE_INFLIGHT].\nThe default value is used for a web Component; there is no default for a TCP/UDP Component.\n",
+ "enum": [
+ "HEADER",
+ "CONNECT",
+ "FIRST_BYTE",
+ "LAST_BYTE",
+ "LAST_BYTE_INFLIGHT"
+ ],
+ "default": "HEADER"
+ }
+ }
+ },
+ "RandomLBMethod": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "RANDOM"
+ ]
+ },
+ "twoServerLBMethod": {
+ "type": "string",
+ "description": "Values applicable to a Web Component are: [LEAST_CONNECTIONS, LEAST_TIME_HEADER, LEAST_TIME_LAST_BYTE];\nValues applicable to a TCP/UDP Component are: [LEAST_CONNECTIONS, LEAST_TIME_CONNECT, LEAST_TIME_FIRST_BYTE, LEAST_TIME_LAST_BYTE].\n",
+ "enum": [
+ "LEAST_CONNECTIONS",
+ "LEAST_TIME_HEADER",
+ "LEAST_TIME_CONNECT",
+ "LEAST_TIME_FIRST_BYTE",
+ "LEAST_TIME_LAST_BYTE"
+ ]
+ }
+ }
+ },
+ "LoadBalancingMethod": {
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "ROUND_ROBIN": "#/components/schemas/RoundRobinLB",
+ "IPHASH": "#/components/schemas/IPHashLB",
+ "LEAST_CONNECTIONS": "#/components/schemas/LeastConnLB",
+ "HASH": "#/components/schemas/HashLBMethod",
+ "LEAST_TIME": "#/components/schemas/LeastTimeLBMethod",
+ "RANDOM": "#/components/schemas/RandomLBMethod"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/RoundRobinLB"
+ },
+ {
+ "$ref": "#/components/schemas/IPHashLB"
+ },
+ {
+ "$ref": "#/components/schemas/LeastConnLB"
+ },
+ {
+ "$ref": "#/components/schemas/HashLBMethod"
+ },
+ {
+ "$ref": "#/components/schemas/LeastTimeLBMethod"
+ },
+ {
+ "$ref": "#/components/schemas/RandomLBMethod"
+ }
+ ]
+ },
+ "DNSServiceDiscovery": {
+ "required": [
+ "servers"
+ ],
+ "properties": {
+ "servers": {
+ "type": "array",
+ "description": "Array of DNS servers. Possible options are:\n- An IPv4 address with an optional port number.\n Port 53 is used if not specified.\n For example, \"10.1.1.1\", \"10.1.1.1:5353\".\n- An IPv6 address with an optional port number.\n Port 53 is used if not specified.\n For example, \"[2001::1]\", \"[2001::1]:5353\",\n- Fully qualified domain name (FQDN). ASCII characters only.\n NGINX uses the OS name server configuration\n to identify the IP addresses of the DNS servers to use.\n",
+ "items": {
+ "type": "string",
+ "pattern": "^(?:(?:(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)(?::(?:[1-9]|[1-5]?[0-9]{2,4}|6[1-4][0-9]{3}|65[1-4][0-9]{2}|655[1-2][0-9]|6553[1-5]))?$)|(?:\\[\\s*(?:(?:(?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:))|(?:(?:[0-9a-fA-F]{1,4}:){6}(?::[0-9a-fA-F]{1,4}|(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(?:(?:[0-9a-fA-F]{1,4}:){5}(?:(?:(?::[0-9a-fA-F]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(?:(?:[0-9a-fA-F]{1,4}:){4}(?:(?:(?::[0-9a-fA-F]{1,4}){1,3})|(?:(?::[0-9a-fA-F]{1,4})?:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(?:(?:[0-9a-fA-F]{1,4}:){3}(?:(?:(?::[0-9a-fA-F]{1,4}){1,4})|(?:(?::[0-9a-fA-F]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(?:(?:[0-9a-fA-F]{1,4}:){2}(?:(?:(?::[0-9a-fA-F]{1,4}){1,5})|(?:(?::[0-9a-fA-F]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(?:(?:[0-9a-fA-F]{1,4}:){1}(?:(?:(?::[0-9a-fA-F]{1,4}){1,6})|(?:(?::[0-9a-fA-F]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(?::(?:(?:(?::[0-9a-fA-F]{1,4}){1,7})|(?:(?::[0-9a-fA-F]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(?:%.+)?](?::(?:[1-9]|[1-5]?[0-9]{2,4}|6[1-4][0-9]{3}|65[1-4][0-9]{2}|655[1-2][0-9]|6553[1-5]))?\\s*$)|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*$))",
+ "minLength": 1,
+ "example": "10.1.1.1:5353"
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "ttl": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$",
+ "description": "Overrides the TTL setting present in the DNS record.",
+ "example": "10s"
+ },
+ "timeout": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$",
+ "description": "Sets the timeout for domain name resolution.",
+ "example": "10s"
+ }
+ }
+ },
+ "WorkloadGroupCommon": {
+ "description": "Settings common to Web and TCP/UDP workloadGroups.",
+ "type": "object",
+ "properties": {
+ "locationRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "loadBalancingMethod": {
+ "$ref": "#/components/schemas/LoadBalancingMethod"
+ },
+ "dnsServiceDiscovery": {
+ "$ref": "#/components/schemas/DNSServiceDiscovery"
+ }
+ }
+ },
+ "WebProxy": {
+ "description": "Proxy retry and timeout settings applicable to servers in a Web workloadGroup associated with a Component.",
+ "type": "object",
+ "properties": {
+ "nextUpstream": {
+ "description": "Specifies in which cases a request should be passed to the next server.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "ERROR",
+ "TIMEOUT",
+ "INVALID_HEADER",
+ "HTTP_500",
+ "HTTP_502",
+ "HTTP_503",
+ "HTTP_504",
+ "HTTP_403",
+ "HTTP_404",
+ "HTTP_429",
+ "NON_IDEMPOTENT",
+ "OFF"
+ ]
+ }
+ },
+ "connectTimeout": {
+ "description": "Defines a timeout for establishing a connection with a proxied server.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$"
+ },
+ "sendTimeout": {
+ "description": "Sets a timeout for transmitting a request to the proxied server.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$"
+ }
+ }
+ },
+ "SessionPersistenceCookie": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "COOKIE"
+ ]
+ },
+ "srvID": {
+ "type": "string"
+ },
+ "expireTime": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$"
+ },
+ "domain": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ }
+ }
+ },
+ "SessionPersistenceRoute": {
+ "type": "object",
+ "required": [
+ "type",
+ "routeInfoLocation"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "ROUTE"
+ ]
+ },
+ "routeInfoLocation": {
+ "type": "string",
+ "enum": [
+ "COOKIE",
+ "URI",
+ "BOTH"
+ ]
+ }
+ }
+ },
+ "SessionPersistenceCookieLearn": {
+ "type": "object",
+ "required": [
+ "type",
+ "create",
+ "lookup"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "COOKIE_LEARN"
+ ]
+ },
+ "create": {
+ "type": "string",
+ "pattern": "^\\$.+"
+ },
+ "lookup": {
+ "type": "string",
+ "pattern": "^\\$.+"
+ }
+ }
+ },
+ "SessionPersistence": {
+ "description": "SessionPersistence settings in a Web workloadGroup.",
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "COOKIE": "#/components/schemas/SessionPersistenceCookie",
+ "ROUTE": "#/components/schemas/SessionPersistenceRoute",
+ "COOKIE_LEARN": "#/components/schemas/SessionPersistenceCookieLearn"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/SessionPersistenceCookie"
+ },
+ {
+ "$ref": "#/components/schemas/SessionPersistenceRoute"
+ },
+ {
+ "$ref": "#/components/schemas/SessionPersistenceCookieLearn"
+ }
+ ]
+ },
+ "WorkloadUri": {
+ "type": "object",
+ "properties": {
+ "weight": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ },
+ "maxConns": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "maxFails": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "failTimeout": {
+ "x-f5-experimental": true,
+ "type": "string",
+ "default": "10s",
+ "pattern": "^[0-9]+[h|m|s]{1}$"
+ },
+ "isBackup": {
+ "type": "boolean",
+ "default": false
+ },
+ "isDown": {
+ "type": "boolean",
+ "default": false
+ },
+ "route": {
+ "x-f5-experimental": true,
+ "type": "string"
+ },
+ "srvService": {
+ "type": "string"
+ },
+ "slowStart": {
+ "x-f5-experimental": true,
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "isDrain": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "WebWorkloadGroup": {
+ "description": "Group of servers hosting a part of a Web application represented by a Component.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/WorkloadGroupCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "proxy": {
+ "$ref": "#/components/schemas/WebProxy"
+ },
+ "sessionPersistence": {
+ "$ref": "#/components/schemas/SessionPersistence"
+ },
+ "uris": {
+ "type": "object",
+ "description": "The URI for a server hosting a part of a Web application.\n\nIt must conform to the format `schema://address[:port]`\nwhere schema is chosen from http or https, address is IP or hostname,\nschema and address must be provided.\n\nFor example:\n\n- `http://192.0.2.247`\n- `https://192.0.2.247:8443`\n- `https://www.f5workload.com`\n",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/WorkloadUri"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "BackendBuffers": {
+ "description": "Proxy buffer settings applicable to servers across all Web workloadGroups associated with a Component.",
+ "type": "object",
+ "properties": {
+ "headerSize": {
+ "description": "Sets the size of the buffer used for reading the first part of the response received from the proxied server.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size"
+ }
+ },
+ "isEnabled": {
+ "description": "Enables or disables buffering of responses from the proxied server.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering"
+ }
+ },
+ "size": {
+ "description": "Sets the number and size of the buffers used for reading a response from the proxied server, for a single connection.",
+ "type": "object",
+ "properties": {
+ "number": {
+ "type": "integer"
+ },
+ "size": {
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$"
+ }
+ },
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers"
+ }
+ },
+ "busySize": {
+ "description": "When buffering of responses from the proxied server is enabled, it limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size"
+ }
+ },
+ "ignoreClientAbort": {
+ "description": "Determines whether the connection with a proxied server should be closed when a client closes the connection without waiting for a response.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort"
+ }
+ },
+ "forceRanges": {
+ "description": "Enables byte-range support for both cached and uncached responses from the proxied server regardless of the \"Accept-Ranges\" field in these responses.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_force_ranges"
+ }
+ },
+ "httpVersion": {
+ "description": "This field is deprecated. Use 'Backend.httpVersion' to set the desired HTTP Version.",
+ "type": "string",
+ "enum": [
+ "1.0",
+ "1.1"
+ ],
+ "deprecated": true,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version"
+ }
+ },
+ "rate": {
+ "description": "Limits the speed (in bytes per second) of reading the response from the proxied server.\nDisables rate limiting when set to `0`.\n",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_limit_rate"
+ }
+ },
+ "readTimeout": {
+ "description": "Defines a timeout for reading a response from the proxied server.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout"
+ }
+ },
+ "maxTempFileSize": {
+ "description": "Sets the maximum size of the temporary file that the response can be saved into. Note that the buffering of responses from proxied server is enabled and the response does not fit into the buffers.\n\nDisables temporary file usage when set to 0.\n",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_max_temp_file_size"
+ }
+ },
+ "tempFileWriteSize": {
+ "description": "Limits the size of data written to a temporary file at a time, when buffering of responses from the proxied server to temporary files is enabled.\n\nDisables temporary file usage when set to 0.\n",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_file_write_size"
+ }
+ }
+ }
+ },
+ "WebBackend": {
+ "description": "Backend settings in a Web Component.\n",
+ "type": "object",
+ "properties": {
+ "keepAlive": {
+ "type": "object",
+ "properties": {
+ "connections": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "requestsPerConn": {
+ "type": "integer"
+ },
+ "idleTimeout": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$",
+ "example": "1h"
+ }
+ }
+ },
+ "monitoring": {
+ "$ref": "#/components/schemas/WebMonitoring"
+ },
+ "workloadGroups": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/WebWorkloadGroup"
+ }
+ },
+ "preserveHostHeader": {
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "queue": {
+ "x-f5-experimental": true,
+ "type": "object",
+ "required": [
+ "length"
+ ],
+ "properties": {
+ "length": {
+ "type": "integer"
+ },
+ "timeOut": {
+ "type": "string",
+ "pattern": "^[0-9]+[h|m|s]{1}$",
+ "example": "1h"
+ }
+ }
+ },
+ "httpVersion": {
+ "description": "Sets the HTTP protocol version for proxying.",
+ "type": "string",
+ "pattern": "^[1-3]{1}\\.[0-1]{1}$",
+ "example": 1
+ },
+ "ntlmAuthentication": {
+ "description": "Allows proxying requests with NTLM Authentication.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "externalDocs": {
+ "url": "http://nginx.org/en/docs/http/ngx_http_upstream_module.html#ntlm"
+ }
+ },
+ "persistentState": {
+ "x-f5-experimental": true,
+ "type": "string"
+ },
+ "buffers": {
+ "$ref": "#/components/schemas/BackendBuffers"
+ },
+ "isSocketKeepaliveEnabled": {
+ "description": "Configures the “TCP keepalive” behavior for outgoing connections to a proxied server.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_socket_keepalive"
+ }
+ },
+ "ignoreHeaders": {
+ "description": "Disables processing of certain response header fields from the proxied server.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "example": [
+ "X-Accel-Redirect",
+ "X-Accel-Expires",
+ "X-Accel-Limit-Rate",
+ "X-Accel-Buffering",
+ "X-Accel-Charset",
+ "Expires",
+ "Cache-Control",
+ "Set-Cookie",
+ "Vary"
+ ],
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers"
+ }
+ },
+ "debugHeaders": {
+ "description": "Permits passing otherwise disabled header fields from a proxied server to a client.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "example": [
+ "X-Accel-Redirect",
+ "X-Accel-Expires",
+ "X-Accel-Limit-Rate",
+ "X-Accel-Buffering",
+ "X-Accel-Charset",
+ "Expires",
+ "Cache-Control",
+ "Set-Cookie",
+ "Vary"
+ ],
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_header"
+ }
+ },
+ "tls": {
+ "description": "TLS settings applicable to servers in Web workloadGroups.",
+ "type": "object",
+ "properties": {
+ "cipher": {
+ "description": "Specifies the enabled ciphers for requests to a proxied HTTPS server.",
+ "type": "string",
+ "example": "ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_ciphers"
+ }
+ },
+ "name": {
+ "description": "Allows overriding the server name used to verify the certificate of the proxied HTTPS server.",
+ "type": "string",
+ "example": "$proxy_host",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_name"
+ }
+ },
+ "protocols": {
+ "description": "Enables the specified protocols for requests to a proxied HTTPS server.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "TLSv1|TLSv1\\.[1-3]|SSLv2|SSLv3"
+ },
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_protocols"
+ }
+ },
+ "isServerNameEnabled": {
+ "description": "Enables or disables passing of the server name through TLS Server Name Indication extension (SNI, RFC 6066) when establishing a connection with the proxied HTTPS server.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_server_name"
+ }
+ },
+ "isSessionReuseEnabled": {
+ "description": "Determines whether SSL sessions can be reused when working with the proxied server.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_session_reuse"
+ }
+ },
+ "isVerifiedEnabled": {
+ "description": "Enables or disables verification of the proxied HTTPS server certificate.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify"
+ }
+ },
+ "verifyDepth": {
+ "description": "Sets the verification depth in the proxied HTTPS server certificates chain.",
+ "type": "integer",
+ "minimum": 0,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify_depth"
+ }
+ }
+ }
+ }
+ }
+ },
+ "UriRewrite": {
+ "type": "object",
+ "required": [
+ "incomingPattern",
+ "rewritePattern"
+ ],
+ "properties": {
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ },
+ "incomingPattern": {
+ "type": "string",
+ "description": "The regex pattern to match against the request URIs that are expected to be rewritten."
+ },
+ "rewritePattern": {
+ "type": "string",
+ "description": "The replacement regex pattern to apply to the URIs that are to be rewritten.",
+ "minLength": 1
+ },
+ "afterExecute": {
+ "type": "string",
+ "enum": [
+ "NONE",
+ "LAST",
+ "BREAK",
+ "REDIRECT",
+ "PERMANENT"
+ ],
+ "default": "BREAK"
+ }
+ }
+ },
+ "UriRedirect": {
+ "type": "object",
+ "required": [
+ "responseCode"
+ ],
+ "properties": {
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ },
+ "responseCode": {
+ "type": "integer",
+ "minimum": 300,
+ "maximum": 308
+ },
+ "url": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The return url to use for responses in the 301-308 range."
+ },
+ "text": {
+ "type": "string",
+ "description": "The return text to send for 300 responses."
+ }
+ }
+ },
+ "ProgrammabilityAction": {
+ "type": "string",
+ "enum": [
+ "ADD",
+ "MODIFY",
+ "DELETE"
+ ]
+ },
+ "CookieModification": {
+ "type": "object",
+ "required": [
+ "action",
+ "cookieName"
+ ],
+ "properties": {
+ "action": {
+ "$ref": "#/components/schemas/ProgrammabilityAction"
+ },
+ "cookieName": {
+ "type": "string"
+ },
+ "cookieValue": {
+ "type": "string"
+ }
+ }
+ },
+ "ProgrammabilityAddRequestHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName",
+ "headerValue"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Adds request header details.",
+ "enum": [
+ "ADD"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the response header to modify.",
+ "minLength": 1
+ },
+ "headerValue": {
+ "type": "string",
+ "description": "The value to apply to the request header.",
+ "minLength": 1
+ },
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ }
+ }
+ },
+ "ProgrammabilityDeleteRequestHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Deletes request header details.",
+ "enum": [
+ "DELETE"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the request header to modify.",
+ "minLength": 1
+ },
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ }
+ }
+ },
+ "RequestHeaderModification": {
+ "type": "object",
+ "discriminator": {
+ "propertyName": "action",
+ "mapping": {
+ "ADD": "#/components/schemas/ProgrammabilityAddRequestHeader",
+ "DELETE": "#/components/schemas/ProgrammabilityDeleteRequestHeader"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ProgrammabilityAddRequestHeader"
+ },
+ {
+ "$ref": "#/components/schemas/ProgrammabilityDeleteRequestHeader"
+ }
+ ]
+ },
+ "ProgrammabilityAddResponseHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName",
+ "headerValue"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Adds response header details.",
+ "enum": [
+ "ADD"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the response header to modify.",
+ "minLength": 1
+ },
+ "headerValue": {
+ "type": "string",
+ "description": "The value to apply to the response header.",
+ "minLength": 1
+ },
+ "responseCodeFilter": {
+ "type": "string",
+ "description": "The value to apply to the response code filter.",
+ "enum": [
+ "ALWAYS",
+ "PRE_DEFINED"
+ ],
+ "default": "PRE_DEFINED"
+ },
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ }
+ }
+ },
+ "ProgrammabilityDeleteResponseHeader": {
+ "type": "object",
+ "required": [
+ "action",
+ "headerName"
+ ],
+ "properties": {
+ "action": {
+ "type": "string",
+ "description": "Deletes response header details.",
+ "enum": [
+ "DELETE"
+ ]
+ },
+ "headerName": {
+ "type": "string",
+ "description": "The name of the response header to modify.\n\n> Warning: `Date`, `Content-Length`, and `Connection` headers cannot be deleted.\n",
+ "minLength": 1
+ },
+ "applicableURIs": {
+ "$ref": "#/components/schemas/ApplicableUris"
+ }
+ }
+ },
+ "ResponseHeaderModification": {
+ "type": "object",
+ "discriminator": {
+ "propertyName": "action",
+ "mapping": {
+ "ADD": "#/components/schemas/ProgrammabilityAddResponseHeader",
+ "DELETE": "#/components/schemas/ProgrammabilityDeleteResponseHeader"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/ProgrammabilityAddResponseHeader"
+ },
+ {
+ "$ref": "#/components/schemas/ProgrammabilityDeleteResponseHeader"
+ }
+ ]
+ },
+ "Programmability": {
+ "type": "object",
+ "properties": {
+ "uriRewrites": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UriRewrite"
+ }
+ },
+ "httpHttpsRedirect": {
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "uriRedirects": {
+ "x-f5-experimental": true,
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/UriRedirect"
+ }
+ },
+ "cookieModifications": {
+ "x-f5-experimental": true,
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CookieModification"
+ }
+ },
+ "requestHeaderModifications": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RequestHeaderModification"
+ }
+ },
+ "responseHeaderModifications": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResponseHeaderModification"
+ }
+ }
+ }
+ },
+ "Logging": {
+ "description": "Settings for error logs and access logs.",
+ "type": "object",
+ "properties": {
+ "errorLog": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "accessLog": {
+ "type": "object",
+ "properties": {
+ "state": {
+ "$ref": "#/components/schemas/ServiceConfigState"
+ },
+ "format": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "WAF": {
+ "description": "Defines the desired configurations for the WAF associated with the application component.",
+ "properties": {
+ "isEnabled": {
+ "type": "boolean",
+ "default": true,
+ "description": "Indicates whether the WAF is enabled or not."
+ },
+ "isMonitorOnly": {
+ "type": "boolean",
+ "default": true,
+ "description": "Indicates whether the WAF will monitor or block security violations."
+ },
+ "signatureOverrides": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "action": {
+ "type": "string",
+ "enum": [
+ "IGNORE"
+ ]
+ }
+ },
+ "description": "Identifies overrides for the signatures contained within the associated security strategy.\n",
+ "example": {
+ "1234": {
+ "action": "IGNORE"
+ },
+ "1235": {
+ "action": "IGNORE"
+ }
+ }
+ }
+ }
+ }
+ },
+ "APIKeyClientAuth": {
+ "description": "Defines how an API client should provide their API Key credentials.",
+ "required": [
+ "keyLocation"
+ ],
+ "properties": {
+ "keyLocation": {
+ "type": "string",
+ "enum": [
+ "HEADER",
+ "QUERY_PARAM"
+ ]
+ },
+ "key": {
+ "type": "string"
+ }
+ }
+ },
+ "JWTClientAuth": {
+ "description": "Defines how an API Client should provide their JWT.",
+ "required": [
+ "keyLocation"
+ ],
+ "properties": {
+ "keyLocation": {
+ "type": "string",
+ "enum": [
+ "BEARER",
+ "HEADER",
+ "QUERY_PARAM",
+ "COOKIE"
+ ]
+ },
+ "key": {
+ "type": "string"
+ }
+ }
+ },
+ "ConditionalAuthPolicy": {
+ "description": "Defines further fine-grained access control on top of API Key or JWT Auth.",
+ "required": [
+ "sourceType",
+ "comparisonType",
+ "comparisonValues",
+ "action",
+ "denyStatusCode"
+ ],
+ "properties": {
+ "sourceType": {
+ "type": "string",
+ "enum": [
+ "HEADER",
+ "JWT_CLAIM"
+ ]
+ },
+ "sourceKey": {
+ "type": "string"
+ },
+ "comparisonType": {
+ "type": "string",
+ "enum": [
+ "EQUALS",
+ "NOT_EQUALS",
+ "IN",
+ "CONTAINS"
+ ]
+ },
+ "comparisonValues": {
+ "type": "array",
+ "description": "Valid values for the sourceType.",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "integer"
+ }
+ ]
+ }
+ },
+ "action": {
+ "type": "string",
+ "enum": [
+ "ALLOW",
+ "DENY"
+ ]
+ },
+ "denyStatusCode": {
+ "type": "integer"
+ }
+ }
+ },
+ "RateLimit": {
+ "required": [
+ "rate"
+ ],
+ "properties": {
+ "rate": {
+ "type": "string",
+ "pattern": "^[0-9]+r\\/[m|s]{1}$",
+ "description": "Sets the maximum number of allowed requests.\n\nYou can specify the rate limit as requests per second (r/s) or requests per minute (r/m).\n",
+ "example": "10r/s"
+ },
+ "burstBeforeReject": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "burstBeforeDelay": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "statusCode": {
+ "type": "integer",
+ "default": 429
+ },
+ "key": {
+ "type": "string",
+ "default": "$binary_remote_addr",
+ "description": "Parameters (NGINX variable) for a shared memory zone that stores states for various keys; used for `limit_req_zone`."
+ }
+ }
+ },
+ "Security": {
+ "type": "object",
+ "description": "Defines the desired security configurations for the application component.",
+ "properties": {
+ "strategyRef": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "waf": {
+ "$ref": "#/components/schemas/WAF"
+ },
+ "identityProviderRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "description": "The list of Identity Providers that are used in this Security policy."
+ },
+ "apiKeyClientAuth": {
+ "$ref": "#/components/schemas/APIKeyClientAuth"
+ },
+ "jwtClientAuth": {
+ "$ref": "#/components/schemas/JWTClientAuth"
+ },
+ "conditionalAuthPolicies": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/ConditionalAuthPolicy"
+ }
+ },
+ "rateLimits": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/RateLimit"
+ }
+ },
+ "interceptWorkloadErrors": {
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState"
+ }
+ }
+ },
+ "InstanceGroupRef": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "listenIps": {
+ "description": "The list of Listen IP addresses.\nSets the BIG-IP virtual address(es) on which the server listens for and accepts requests.\n",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$",
+ "example": "1.1.1.1"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "Placement": {
+ "description": "Instances that have NGINX configuration applied corresponding to the Gateway and associated Components settings.",
+ "type": "object",
+ "properties": {
+ "instanceRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InstanceRef"
+ }
+ },
+ "instanceGroupRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InstanceGroupRef"
+ }
+ }
+ }
+ },
+ "GatewayIngressCommon": {
+ "description": "Ingress settings in a Gateway that apply to Web and TCP/UDP Components.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/GatewaySocketSettings"
+ },
+ {
+ "type": "object",
+ "required": [
+ "uris",
+ "placement"
+ ],
+ "properties": {
+ "uris": {
+ "$ref": "#/components/schemas/IngressUris"
+ },
+ "tls": {
+ "$ref": "#/components/schemas/TLS"
+ },
+ "placement": {
+ "$ref": "#/components/schemas/Placement"
+ }
+ }
+ }
+ ]
+ },
+ "HeaderMatchMethod": {
+ "type": "string",
+ "enum": [
+ "PREFIX",
+ "REGEX",
+ "REGEX_CASE_SENSITIVE",
+ "SUFFIX",
+ "EXACT"
+ ],
+ "default": "REGEX"
+ },
+ "IngressHeader": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "nameMatchMethod": {
+ "$ref": "#/components/schemas/HeaderMatchMethod"
+ },
+ "value": {
+ "type": "string"
+ },
+ "valueMatchMethod": {
+ "$ref": "#/components/schemas/HeaderMatchMethod"
+ }
+ }
+ },
+ "WebIngressCommon": {
+ "description": "Ingress settings in a Gateway and Component that apply only to Web Components.",
+ "type": "object",
+ "properties": {
+ "methods": {
+ "description": "Specifies the HTTP method to use in requests.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "POST",
+ "GET",
+ "PUT",
+ "DELETE",
+ "PATCH",
+ "HEAD",
+ "TRACE",
+ "OPTIONS",
+ "CONNECT"
+ ]
+ }
+ },
+ "clientMaxBodySize": {
+ "description": "Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field.",
+ "type": "string",
+ "pattern": "^[0-9]+[k|K|m|M]{1}$",
+ "deprecated": true,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size"
+ }
+ },
+ "headers": {
+ "description": "Specifies the match method for headers to be used in requests.",
+ "x-f5-experimental": true,
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/IngressHeader"
+ }
+ },
+ "http2": {
+ "description": "Enable or disable HTTP/2 connections on the port. Normally, for this to work the `ssl` parameter should be specified as well,\nbut NGINX can also be configured to accept HTTP/2 connections without SSL.\nPossible values are `ENABLED` or `DISABLED`.\n",
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#listen"
+ }
+ },
+ "spdy": {
+ "description": "Enables or disables acceptance of the SPDY connections on the specified port.\nNormally, for this to work the `ssl` parameter should be specified as well,\nbut NGINX can also be configured to accept SPDY connections without SSL. Possible values are `ENABLED` or `DISABLED`.\n",
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#listen"
+ }
+ },
+ "proxyProtocol": {
+ "description": "Enables or disables the proxy protocol for all connections accepted on the specified port.\nThe `proxy protocol` enables NGINX and NGINX Plus to receive client connection information passed through proxy servers and load balancers,\nsuch as HAproxy and Amazon Elastic Load Balancer (ELB). The possible values are `ENABLED` or `DISABLED`.\n",
+ "x-f5-experimental": true,
+ "$ref": "#/components/schemas/ServiceConfigState",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#listen"
+ }
+ },
+ "notFoundStatusCode": {
+ "x-f5-experimental": true,
+ "type": "integer",
+ "default": 404
+ },
+ "headersHashBucketSize": {
+ "description": "Sets the bucket size for hash tables used by the `proxy_hide_header` and `proxy_set_header` directives.",
+ "type": "integer",
+ "minimum": 1,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_bucket_size"
+ }
+ },
+ "headersHashMaxSize": {
+ "description": "Sets the maximum size of hash tables used by the `proxy_hide_header` and `proxy_set_header` directives.",
+ "type": "integer",
+ "minimum": 1,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size"
+ }
+ }
+ }
+ },
+ "GatewayWebIngressClient": {
+ "description": "Non-buffer settings in a Gateway applicable to Web client requests.",
+ "type": "object",
+ "properties": {
+ "bodyInFileOnly": {
+ "description": "Determines whether NGINX Controller should save the entire client request body into a file.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED",
+ "CLEAN"
+ ],
+ "default": "DISABLED",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_file_only"
+ }
+ },
+ "bodyTimeout": {
+ "description": "Defines a timeout for reading the client request body.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout"
+ }
+ },
+ "headerTimeout": {
+ "description": "Defines a timeout for reading the client request header.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[hms]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout"
+ }
+ },
+ "maxBodySize": {
+ "description": "Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field.\n\nDisables checking of client request body size when set to 0.\n",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size"
+ }
+ }
+ }
+ },
+ "WebIngressBuffersCommon": {
+ "description": "Buffer settings common to a Gateway and Component applicable to web client requests.",
+ "type": "object",
+ "properties": {
+ "clientBodyBufferingIsEnabled": {
+ "description": "Enables or disables buffering of a client request body.",
+ "type": "boolean",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering"
+ }
+ },
+ "clientBodyBufferSize": {
+ "description": "Sets the buffer size for reading the client request body.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size"
+ }
+ },
+ "clientBodyInSingleBuffer": {
+ "description": "Determines whether NGINX Controller should save the entire client request body in a single buffer.",
+ "type": "string",
+ "enum": [
+ "ENABLED",
+ "DISABLED"
+ ],
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_single_buffer"
+ }
+ }
+ }
+ },
+ "GatewayWebIngress": {
+ "description": "Ingress settings in a Gateway that apply only to Web Components.",
+ "type": "object",
+ "properties": {
+ "client": {
+ "$ref": "#/components/schemas/GatewayWebIngressClient"
+ },
+ "allowUnderscoresInHeaders": {
+ "type": "boolean",
+ "default": false,
+ "description": "Allows the use of underscores in client request header fields.\n\nWhen set to `disabled`, request headers with names that contain underscores are considered invalid and are ignored.\n"
+ },
+ "buffers": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/WebIngressBuffersCommon"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "clientHeaderBufferSize": {
+ "description": "Sets the buffer size for reading the client request header.",
+ "type": "string",
+ "pattern": "^[0-9]{1,12}[kKmM]?$",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "GatewayIngress": {
+ "description": "Ingress settings in a Gateway.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/GatewayIngressCommon"
+ },
+ {
+ "$ref": "#/components/schemas/WebIngressCommon"
+ },
+ {
+ "$ref": "#/components/schemas/GatewayWebIngress"
+ }
+ ]
+ },
+ "GatewayDesiredState": {
+ "description": "The desired gateway settings that the user wants in the configuration on NGINX instances referenced by this Gateway.",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/GatewayWebState"
+ },
+ {
+ "$ref": "#/components/schemas/GatewayStateCommon"
+ },
+ {
+ "type": "object",
+ "required": [
+ "ingress"
+ ],
+ "properties": {
+ "ingress": {
+ "$ref": "#/components/schemas/GatewayIngress"
+ }
+ }
+ }
+ ]
+ },
+ "CertMetadata": {
+ "type": "object",
+ "description": "Public certificate metadata.",
+ "required": [
+ "authorityKeyIdentifier",
+ "commonName",
+ "expired",
+ "expiry",
+ "issuer",
+ "publicKeyType",
+ "serialNumber",
+ "signatureAlgorithm",
+ "subject",
+ "subjectAlternativeName",
+ "subjectKeyIdentifier",
+ "thumbprint",
+ "thumbprintAlgorithm",
+ "validFrom",
+ "validTo",
+ "version"
+ ],
+ "properties": {
+ "authorityKeyIdentifier": {
+ "type": "string",
+ "example": "2B D0 69 47 94 76 09 FE F4 6B 8D 2E 40 A6 F7 47 4D 7F 08 5E",
+ "description": "The identifier of the signing authority for the certificate."
+ },
+ "commonName": {
+ "type": "string",
+ "example": "www.myapp.com",
+ "description": "The Common Name (CN) for the certificate. This is typically a Fully Qualified Domain Name (FQDN), and must be the same as the web address users access when connecting to a web site."
+ },
+ "expired": {
+ "type": "boolean",
+ "example": false,
+ "description": "Indicates the expiration status of the certificate."
+ },
+ "expiry": {
+ "type": "integer",
+ "example": 35500034,
+ "description": "The number of seconds until the certificate will expire."
+ },
+ "issuer": {
+ "type": "string",
+ "example": "DigiCert Class 3 Extended Validation SSL SGC CA.",
+ "description": "Identifies the entity who signed and issued the certificate."
+ },
+ "publicKeyType": {
+ "type": "string",
+ "example": "RSA (2048 Bits)",
+ "description": "Identifies the encryption algorithm used to create the public key for the ceritficate."
+ },
+ "serialNumber": {
+ "type": "string",
+ "example": "16469416336579571270",
+ "description": "A unique identifier for the certificate."
+ },
+ "signatureAlgorithm": {
+ "type": "string",
+ "example": "SHA-256",
+ "description": "Identifies the algorithm used to sign the certificate."
+ },
+ "subject": {
+ "type": "string",
+ "example": "www.myapp.com",
+ "description": "Contains the Distinguished Name (DN) information for the certificate."
+ },
+ "subjectAlternativeName": {
+ "type": "string",
+ "example": "DNS Name=static.xxxx",
+ "description": "Defines additional identifies bound to the subject of the certificate. For example, the DNS name is used to add addtional domain names to a certificate."
+ },
+ "subjectKeyIdentifier": {
+ "type": "string",
+ "example": "31 EA 76 A9 23 74 A5 DF D4 FD EE A0 C1 A6 9E C6 11 0E 11 EC",
+ "description": "A hash value of the SSL certificate that can be used to identify certificates that contain a particular public key."
+ },
+ "thumbprint": {
+ "type": "string",
+ "example": "E6 A7 87 96 E0 C7 A3 E5 43 78 35 CA 16 78 5B 48 5A A9 DD C4 5C CD 0A 65 AA 89 33 E3 C3 D0 89 71",
+ "description": "A hash to ensure that the certificate has not been modified."
+ },
+ "thumbprintAlgorithm": {
+ "type": "string",
+ "example": "SHA-1",
+ "description": "Defines the algorithm used to hash the certificate."
+ },
+ "validFrom": {
+ "type": "string",
+ "example": "2019-07-29T09:12:33.001Z",
+ "description": "The start of the validity period for the certificate."
+ },
+ "validTo": {
+ "type": "string",
+ "example": "2029-07-29T09:12:33.001Z",
+ "description": "The end of the validity period for the certificate."
+ },
+ "version": {
+ "type": "integer",
+ "example": 3,
+ "description": "The version of the certificate, typically 3 for X.509 certificates."
+ }
+ }
+ },
+ "CertDesiredState": {
+ "type": "object",
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "PEM": "#/components/schemas/PEM",
+ "PKCS12": "#/components/schemas/PKCS12",
+ "REMOTE_FILE": "#/components/schemas/RemoteFile"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/PEM"
+ },
+ {
+ "$ref": "#/components/schemas/PKCS12"
+ },
+ {
+ "$ref": "#/components/schemas/RemoteFile"
+ }
+ ]
+ },
+ "CertList": {
+ "type": "object",
+ "required": [
+ "items"
+ ],
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/CertStatus"
+ }
+ }
+ }
+ },
+ "CertStatus": {
+ "type": "object",
+ "required": [
+ "metadata",
+ "desiredState",
+ "currentStatus"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/CertDesiredState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/CertCurrentStatus"
+ }
+ }
+ },
+ "CertCurrentStatus": {
+ "type": "object",
+ "description": "'Shows the current status of the certificate.\n\nWhen any certificates have expired, the Certs service sets `state.selfConfigState.isConfigured` and `state.selfConfigState.isError` to `true`. The service will also add a value to the conditons array with the type \"expiration\" and a message that shows when the first certificate will expire. For example, `conditions: [{type: \"expiration\", message: \"Certificate www.example.com will expire in 29 days.\"}])`'\n",
+ "required": [
+ "state",
+ "certMetadata",
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "privateKey": {
+ "type": "string"
+ },
+ "publicCert": {
+ "type": "string"
+ },
+ "data": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "caCerts": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "certMetadata": {
+ "type": "array",
+ "description": "Public certificate metadata.",
+ "items": {
+ "$ref": "#/components/schemas/CertMetadata"
+ }
+ }
+ }
+ },
+ "Cert": {
+ "type": "object",
+ "description": "Contains the certificate to upload.",
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/CertDesiredState"
+ }
+ }
+ },
+ "PEM": {
+ "type": "object",
+ "description": "Defines a PEM-formatted certificate that contains a key and certificates.\n\nBecause JSON does not support multi-line strings, you must replace binary line feeds with ASCII line feeds (`\\n`).\nThe private key data will be redacted in the response for all get and list requests.\n",
+ "required": [
+ "privateKey",
+ "publicCert",
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "PEM"
+ ]
+ },
+ "password": {
+ "type": "string",
+ "example": "myPa$$w0rd",
+ "description": "The passphrase to use to decrypt the private key. Required if the private key is encrypted."
+ },
+ "privateKey": {
+ "type": "string",
+ "example": "-----BEGIN PRIVATE KEY-----\\n MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALSQBtRafNJtTqN0\\n nYiZq6TZUsHjfG2R9PlK6jsvno9O6amN96Al6ZSTTDjhr4VU7/RJ0p/cisiCboCX\\n 4cCq6lFKpIpeZJI=\\n -----END PRIVATE KEY-----",
+ "description": "The private key used to sign the public certificate.\n\nBecause JSON does not support multi-line strings, you must replace binary line feeds with ASCII line feeds (`\\n`). The private key data will be redacted in the response for all get and list requests.\n"
+ },
+ "publicCert": {
+ "type": "string",
+ "example": "-----BEGIN CERTIFICATE-----\\n MIICpzCCAhACCQDkjx7mP9cuRjANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMC\\n MiJVGawyxDzBm2UhzNOE0ABHfjAgM6PAYmtMhhQawk6bmttXYhJeqhLSji4LEj5d\\n Z4FmXQ5rWM0RWBs=\\n -----END CERTIFICATE-----",
+ "description": "The end-entity certificate, in PEM format.\n\nBecause JSON does not support multi-line strings, you must replace binary line feeds with ASCII line feeds (`\\n`).\n"
+ },
+ "caCerts": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "example": [
+ "-----BEGIN CERTIFICATE-----\\n MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh\\n WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf\\n SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==\\n -----END CERTIFICATE-----"
+ ],
+ "description": "An optional list of intermediate certificates in PEM format that are used to validate the public certificate.\n\nBecause JSON does not support multi-line strings, you must replace binary line feeds with ASCII line feeds (`\\n`).\n"
+ }
+ }
+ },
+ "PKCS12": {
+ "type": "object",
+ "description": "Defines a cert with key and certificates encoded in PKCS12 format.",
+ "required": [
+ "data",
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "PKCS12"
+ ]
+ },
+ "data": {
+ "type": "string",
+ "example": "MIIGoQIBAzCCBmcGCSqGSIb3DQEHAaCCBlgEggZUMIIGUDCCA08GCSqGSIb3DQEHBqCCA0AwggM8AgEAMIIDNQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIe7ZblBoEW3QCAggAgIIDCCgLEvzp9n69QbpGT0MDEwITAJBgUrDgMCGgUABBQJs6ZgeAMcxVLrq1hU+TlUOArMuQQIGK59vCBn0wECAggA",
+ "description": "A base-64-encoded string that contains a private key, a public certificate, and, optionally, other intermediate certificates."
+ },
+ "password": {
+ "type": "string",
+ "example": "myPa$$w0rd",
+ "description": "The password to use to decrypt PKCS12 data."
+ }
+ }
+ },
+ "RemoteFile": {
+ "type": "object",
+ "description": "Define a Cert resource by providing references to remote files.\n\n> **Note:** These are file path references only. The system can not validate the file contents or extract the certificate metadata. Providing a PEM or PKCS12 certificate is recommended.\n",
+ "required": [
+ "privateKey",
+ "publicCert",
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "REMOTE_FILE"
+ ]
+ },
+ "privateKey": {
+ "type": "string",
+ "example": "/certs/www.example.com/example.key",
+ "description": "The path to the private key file."
+ },
+ "publicCert": {
+ "type": "string",
+ "example": "/certs/www.example.com/example.crt",
+ "description": "The path to the certificate bundle file. The file must contain the public certificate and may contain additional intermediate certificates."
+ }
+ }
+ },
+ "IdentityProviderList": {
+ "type": "object",
+ "description": "Contains a list of Identity Provider resources.",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/IdentityProvider"
+ }
+ }
+ }
+ },
+ "APIKeyIdentityProvider": {
+ "required": [
+ "type"
+ ],
+ "type": "object",
+ "description": "Use an API key for authentication.\n\n> **Note:** Use of API Key authN is not recommended in production environments.\n",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "API_KEY"
+ ]
+ }
+ }
+ },
+ "JWTIdentityProvider": {
+ "required": [
+ "jwkFile",
+ "type"
+ ],
+ "type": "object",
+ "description": "Use a JWT for authentication.",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "JWT"
+ ]
+ },
+ "jwkFile": {
+ "description": "Provide the path to - or URI for - a `.jwk` file to use for authentication.\nYou can also provide the `.jwk` file contents inline.\n",
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "INLINE": "#/components/schemas/JWKInline",
+ "REMOTE_FILE": "#/components/schemas/JWKRemoteFile"
+ }
+ },
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/JWKInline"
+ },
+ {
+ "$ref": "#/components/schemas/JWKRemoteFile"
+ }
+ ]
+ }
+ }
+ },
+ "IdentityProviderDesiredState": {
+ "required": [
+ "environmentRefs",
+ "identityProvider"
+ ],
+ "type": "object",
+ "properties": {
+ "environmentRefs": {
+ "description": "The Enviroment associated with the Identity Provider.",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "identityProvider": {
+ "$ref": "#/components/schemas/IdentityProviderData"
+ }
+ },
+ "example": {
+ "environmentRefs": [
+ {
+ "ref": "/services/environments/env1"
+ }
+ ],
+ "identityProvider": {
+ "type": "JWT",
+ "jwkFile": {
+ "type": "REMOTE_FILE",
+ "uri": "https://example.com/keys.jwk",
+ "cacheExpire": "10h"
+ }
+ }
+ }
+ },
+ "IdentityProviderCurrentStatus": {
+ "required": [
+ "environmentRefs",
+ "identityProvider",
+ "state"
+ ],
+ "type": "object",
+ "properties": {
+ "environmentRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "identityProvider": {
+ "$ref": "#/components/schemas/IdentityProviderData"
+ }
+ }
+ },
+ "IdentityProvider": {
+ "required": [
+ "desiredState",
+ "metadata"
+ ],
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/IdentityProviderCurrentStatus"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/IdentityProviderDesiredState"
+ }
+ }
+ },
+ "IdentityProviderData": {
+ "description": "The means of authentication used by the Identity Provider (JWT or APIKey).",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/JWTIdentityProvider"
+ },
+ {
+ "$ref": "#/components/schemas/APIKeyIdentityProvider"
+ }
+ ],
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "API_KEY": "#/components/schemas/APIKeyIdentityProvider",
+ "JWT": "#/components/schemas/JWTIdentityProvider"
+ }
+ }
+ },
+ "IdentityProviderClientDesiredState": {
+ "type": "object",
+ "properties": {
+ "credential": {
+ "$ref": "#/components/schemas/IdentityProviderClientCredential"
+ }
+ }
+ },
+ "IdentityProviderClientCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "credential": {
+ "$ref": "#/components/schemas/IdentityProviderClientCredential"
+ }
+ }
+ },
+ "IdentityProviderClient": {
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/IdentityProviderClientCurrentStatus"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/IdentityProviderClientDesiredState"
+ }
+ }
+ },
+ "IdentityProviderClientCredential": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/IdentityProviderAPIKey"
+ }
+ ],
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "API_KEY": "#/components/schemas/IdentityProviderAPIKey"
+ }
+ }
+ },
+ "IdentityProviderClientList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/IdentityProviderClient"
+ }
+ }
+ }
+ },
+ "UpdateIdentityProviderClient": {
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/IdentityProviderClientCurrentStatus"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/IdentityProviderClientDesiredState"
+ }
+ }
+ },
+ "JWK": {
+ "type": "object",
+ "properties": {
+ "kty": {
+ "type": "string",
+ "description": "The cryptographic algorithm family used with the key, such as \"RSA\" or \"EC\"."
+ },
+ "use": {
+ "type": "string",
+ "description": "The intended use of the public key, whether for encrypting data or verifying the signature on data."
+ },
+ "key_ops": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "The operation(s) for which the key is intended to be used."
+ },
+ "alg": {
+ "type": "string",
+ "description": "The algorithm intended for use with the key."
+ },
+ "kid": {
+ "type": "string",
+ "description": "The key ID used to match a specific key."
+ },
+ "x5u": {
+ "type": "string",
+ "description": "The X.509 URL that refers to a resource for an X.509 public key certificate or certificate chain."
+ },
+ "x5c": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "The X.509 Certificate Chain of one or more PKIX certificates. The PKIX certificate containing the key value MUST be the first certificate."
+ },
+ "x5t": {
+ "type": "string",
+ "description": "The X.509 Certificate SHA-1 Thumbprint (a.k.a. digest) of the DER encoding of an X.509 certificate."
+ },
+ "x5t256": {
+ "type": "string",
+ "description": "The X.509 Certificate SHA-256 Thumbprint (a.k.a. digest) of the DER encoding of an X.509 certificate."
+ },
+ "p2s": {
+ "type": "string",
+ "description": "The salt input value for PBES2 key encryption, which is used as part of the PBKDF2 salt value."
+ },
+ "p2c": {
+ "type": "string",
+ "description": "The PBKDF2 iteration count for PBES2 key encryption, represented as a positive JSON integer. The iteration count adds computational expense, ideally compounded by the possible range of keys introduced by the salt. A minimum iteration count of 1000 is RECOMMENDED."
+ },
+ "crv": {
+ "type": "string",
+ "description": "The cryptographic curve used for an Elliptic Curve public key."
+ },
+ "x": {
+ "type": "string",
+ "description": "The x coordinate of the point for an Elliptic Curve public key."
+ },
+ "y": {
+ "type": "string",
+ "description": "The y coordinate of the point for an Elliptic Curve public key."
+ },
+ "e": {
+ "type": "string",
+ "description": "The exponent value for an RSA public key."
+ },
+ "exp": {
+ "type": "string",
+ "description": "The exponent value for an RSA public key."
+ },
+ "n": {
+ "type": "string",
+ "description": "The modulus value for an RSA public key."
+ },
+ "mod": {
+ "type": "string",
+ "description": "The modulus value for an RSA public key."
+ },
+ "d": {
+ "type": "string",
+ "description": "The private key value for an Elliptic Curve private key OR the private exponent value for an RSA private key."
+ },
+ "p": {
+ "type": "string",
+ "description": "The first prime factor for an RSA private key."
+ },
+ "q": {
+ "type": "string",
+ "description": "The second prime factor for an RSA private key."
+ },
+ "dp": {
+ "type": "string",
+ "description": "The Chinese Remainder Theorem (CRT) exponent of the first factor for an RSA private key."
+ },
+ "dq": {
+ "type": "string",
+ "description": "The CRT exponent of the second factor for an RSA private key."
+ },
+ "qi": {
+ "type": "string",
+ "description": "The CRT coefficient of the second factor for an RSA private key."
+ },
+ "oth": {
+ "description": "An array of information about any third and subsequent primes, should they exist.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "r": {
+ "type": "string",
+ "description": "The prime factor."
+ },
+ "d": {
+ "type": "string",
+ "description": "The factor CRT exponent of the corresponding prime factor."
+ },
+ "t": {
+ "type": "string",
+ "description": "The factor CRT coefficient of the corresponding prime factor."
+ }
+ }
+ }
+ },
+ "iv": {
+ "type": "string",
+ "description": "The base64url-encoded representation of the 96-bit Initialization Vector value used for the AES GCM key encryption operation."
+ },
+ "tag": {
+ "type": "string",
+ "description": "The base64url-encoded representation of the 128-bit Authentication Tag value resulting from the AES GCM key encryption operation."
+ },
+ "k": {
+ "type": "string",
+ "description": "The key value of the symmetric (or other single-valued) key."
+ },
+ "enc": {
+ "type": "string",
+ "description": "The encryption algorithm for JWE."
+ },
+ "epk": {
+ "type": "object",
+ "description": "The ephemeral public key value created by the originator for use in ECDH-ES key agreement algorithms."
+ },
+ "apu": {
+ "type": "string",
+ "description": "The agreement PartyUInfo for ECDH-ES key agreement algorithms, containing information about the producer."
+ },
+ "apv": {
+ "type": "string",
+ "description": "The agreement PartyVInfo for ECDH-ES key agreement algorithms."
+ }
+ }
+ },
+ "JWKInline": {
+ "required": [
+ "type",
+ "keys"
+ ],
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "INLINE"
+ ]
+ },
+ "keys": {
+ "type": "array",
+ "description": "The JSON Web Keys.\n",
+ "items": {
+ "$ref": "#/components/schemas/JWK"
+ },
+ "example": [
+ {
+ "k": "ZmFudGFzdGljand0",
+ "kty": "oct",
+ "kid": 1
+ }
+ ]
+ }
+ },
+ "description": "Inline contents of a JWK JSON file.\n"
+ },
+ "JWKRemoteFile": {
+ "required": [
+ "uri",
+ "type"
+ ],
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "REMOTE_FILE"
+ ]
+ },
+ "uri": {
+ "type": "string"
+ },
+ "cacheExpire": {
+ "pattern": "^[0-9]+[h|m|s]{1}$",
+ "type": "string",
+ "description": "The length of time for which to cache the remote file.\nNGINX will retrieve the file from the source URI when the cache time expires.\n",
+ "example": "10h"
+ }
+ }
+ },
+ "IdentityProviderAPIKey": {
+ "required": [
+ "type"
+ ],
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "API_KEY"
+ ]
+ },
+ "apiKey": {
+ "type": "string",
+ "description": "If left empty, a key will automatically be generated.\nThe apikey must contain only alphanumeric characters, underscores, and hyphens.\nThe length of the apikey must be between 8 - 256 characters.\n",
+ "example": "ADv-2ZheQnL_jVx5klhQ39"
+ }
+ }
+ },
+ "ListInstanceGroupsResponse": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InstanceGroup"
+ }
+ }
+ }
+ },
+ "GetInstanceGroupResponse": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/InstanceGroup"
+ }
+ ]
+ },
+ "InstanceGroup": {
+ "type": "object",
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/InstanceGroupState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/InstanceGroupStatus"
+ }
+ }
+ },
+ "InstanceGroupState": {
+ "type": "object",
+ "properties": {
+ "bigIpIntegration": {
+ "$ref": "#/components/schemas/BigIpIntegration"
+ },
+ "locationRef": {
+ "description": "Reference to location all instances of the group belong to. If not specified, the default 'unspecified' is assumed.",
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ },
+ "InstanceGroupStatus": {
+ "type": "object",
+ "required": [
+ "state"
+ ],
+ "properties": {
+ "instanceRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/InstanceRef"
+ }
+ },
+ "bigIpIntegration": {
+ "$ref": "#/components/schemas/BigIpIntegration"
+ },
+ "locationRef": {
+ "description": "Reference to location all instances of the group belong to. If not specified, the default 'unspecified' is assumed.",
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ }
+ }
+ },
+ "InstanceRef": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ ],
+ "description": "Reference to a member Instance resource."
+ },
+ "BigIpIntegration": {
+ "type": "object",
+ "required": [
+ "integrationRef",
+ "serverPoolIp"
+ ],
+ "properties": {
+ "integrationRef": {
+ "description": "Reference to a BIG-IP Integration object, indicating that the Instances will be members of a BIG-IP server pool.",
+ "$ref": "#/components/schemas/ResourceRef"
+ },
+ "serverPoolIp": {
+ "description": "The Instance IP addresses or CIDR to use when the Instance is a member of a BIG-IP server pool.\nIf this is a CIDR, then the Instance IP address that matches the mask will be the member address in the BIG-IP server pool.\nOtherwise, absolute IP addresses will be used as server-pool member addresses.\n",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "DevPortalsList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/DevPortal"
+ }
+ }
+ }
+ },
+ "DevPortal": {
+ "type": "object",
+ "description": "A Dev Portal.",
+ "required": [
+ "metadata",
+ "desiredState"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/DevPortalDesiredState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/DevPortalCurrentStatus"
+ }
+ },
+ "additionalProperties": false
+ },
+ "DevPortalDesiredState": {
+ "type": "object",
+ "required": [
+ "ingress"
+ ],
+ "properties": {
+ "ingress": {
+ "type": "object",
+ "required": [
+ "gatewayRefs"
+ ],
+ "properties": {
+ "gatewayRefs": {
+ "type": "array",
+ "description": "Reference to the Gateways that act as a Developer Portal.",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "devPortalTheme": {
+ "$ref": "#/components/schemas/DevPortalTheme"
+ },
+ "publishedApiRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "devPortalType": {
+ "type": "string",
+ "enum": [
+ "private",
+ "public",
+ "partner"
+ ]
+ }
+ },
+ "additionalProperties": false
+ },
+ "DevPortalCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "ingress": {
+ "type": "object",
+ "required": [
+ "gatewayRefs"
+ ],
+ "properties": {
+ "gatewayRefs": {
+ "type": "array",
+ "description": "Reference to the Gateways that act as a Developer Portal.",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ }
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "devPortalTheme": {
+ "$ref": "#/components/schemas/DevPortalTheme"
+ },
+ "publishedApiRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "publishedTime": {
+ "type": "string",
+ "format": "date-time",
+ "example": "2019-07-29T10:12:33.001Z",
+ "description": "Published time is a timestamp that represents the server time when the resource was published.\nResources that have never been published do not have an `published_time` stamp.\nThe default value is language-specific and, in general, should be equivalent of the null construct.\nIn JSON format, `published_time` type is encoded as a string as described in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt).\n\nFor example: 2018-04-01T01:30:15.01Z\n"
+ }
+ }
+ },
+ "DevPortalTheme": {
+ "description": "Specifies the theming for the Developer Portal.",
+ "type": "object",
+ "properties": {
+ "overrideDefaultTheme": {
+ "type": "boolean",
+ "example": false,
+ "description": "Override the default Dev Portal theme with a custom theme."
+ },
+ "customConfig": {
+ "type": "object",
+ "properties": {
+ "primary": {
+ "$ref": "#/components/schemas/ThemeConfig"
+ },
+ "secondary": {
+ "$ref": "#/components/schemas/ThemeConfig"
+ },
+ "fonts": {
+ "type": "object",
+ "properties": {
+ "assignments": {
+ "$ref": "#/components/schemas/FontAssignments"
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ },
+ "brandName": {
+ "$ref": "#/components/schemas/BrandName"
+ },
+ "logo": {
+ "$ref": "#/components/schemas/FileEncodedString"
+ },
+ "defaultLogo": {
+ "$ref": "#/components/schemas/FileEncodedString"
+ },
+ "favicon": {
+ "$ref": "#/components/schemas/FileEncodedString"
+ }
+ },
+ "additionalProperties": false
+ },
+ "ThemeConfig": {
+ "type": "object",
+ "properties": {
+ "color": {
+ "$ref": "#/components/schemas/ThemeConfigColors"
+ }
+ },
+ "additionalProperties": false
+ },
+ "ThemeConfigColors": {
+ "type": "object",
+ "properties": {
+ "primary": {
+ "type": "string",
+ "example": "#575fe6",
+ "description": "A CSS color string used as a primary brand theme color."
+ },
+ "accent": {
+ "type": "string",
+ "example": "#48dbac",
+ "description": "A CSS color string used as an optional second brand theme color."
+ },
+ "gray": {
+ "type": "string",
+ "example": "#1e1f27",
+ "description": "A CSS color string used to generate a grayscale color palette."
+ },
+ "link": {
+ "type": "string",
+ "example": "#0f55bd",
+ "description": "A CSS color string used to generate anchor link colors."
+ },
+ "fill": {
+ "type": "string",
+ "example": "#fafbfc",
+ "description": "A CSS color string used as the main background color."
+ },
+ "ink": {
+ "type": "string",
+ "example": "#323441",
+ "description": "A CSS color string used as the main text color."
+ },
+ "status": {
+ "$ref": "#/components/schemas/ThemeConfigStatusColors"
+ }
+ },
+ "additionalProperties": false
+ },
+ "ThemeConfigStatusColors": {
+ "type": "object",
+ "description": "A collection of CSS color strings used to indicate status.",
+ "properties": {
+ "info": {
+ "type": "string",
+ "example": "#20a9ea",
+ "description": "A CSS color string used to indicate an informational status."
+ },
+ "success": {
+ "type": "string",
+ "example": "#37c497",
+ "description": "A CSS color string used to indicate a success status."
+ },
+ "error": {
+ "type": "string",
+ "example": "#ed4f54",
+ "description": "A CSS color string used to indicate an error status."
+ },
+ "warning": {
+ "type": "string",
+ "example": "#ffb900",
+ "description": "A CSS color string used to indicate a warning status."
+ }
+ },
+ "additionalProperties": false
+ },
+ "ThemeConfigFonts": {
+ "type": "object",
+ "description": "A collection of fonts for theming typography.",
+ "properties": {
+ "headings": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ThemeConfigFont"
+ }
+ ],
+ "description": "A font used for headlines."
+ },
+ "body": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ThemeConfigFont"
+ }
+ ],
+ "description": "A font used for body copy."
+ },
+ "cta": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ThemeConfigFont"
+ }
+ ],
+ "description": "A font used for calls to action."
+ },
+ "code": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ThemeConfigFont"
+ }
+ ],
+ "description": "A font used for code and syntax highlighting."
+ },
+ "special": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ThemeConfigFont"
+ }
+ ],
+ "description": "A font used for special accent typography."
+ },
+ "baseFontSize": {
+ "$ref": "#/components/schemas/BaseFontSize"
+ },
+ "embeddedLink": {
+ "$ref": "#/components/schemas/EmbeddedLink"
+ }
+ },
+ "additionalProperties": false
+ },
+ "ThemeConfigFont": {
+ "type": "object",
+ "properties": {
+ "kind": {
+ "type": "string",
+ "enum": [
+ "google-web-font"
+ ]
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "FileEncodedString": {
+ "type": "string",
+ "example": "c29tZXRoaW5nIA==",
+ "description": "Base64 encoded string of a logo."
+ },
+ "BrandName": {
+ "type": "string",
+ "example": "Acme",
+ "description": "Name of the brand."
+ },
+ "BaseFontSize": {
+ "type": "integer",
+ "example": 14
+ },
+ "EmbeddedLink": {
+ "type": "string"
+ },
+ "FontAssignments": {
+ "type": "object",
+ "$ref": "#/components/schemas/ThemeConfigFonts"
+ },
+ "EnvironmentName": {
+ "type": "string"
+ },
+ "EnvironmentList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Environment"
+ }
+ }
+ }
+ },
+ "Environment": {
+ "type": "object",
+ "description": "An Environment is a logical container that you can use to organize your Apps. A few commonly-used examples of Environments are \"dev\" and \"production\".",
+ "required": [
+ "metadata"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "desiredState": {
+ "x-f5-experimental": true,
+ "type": "object"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/EnvironmentCurrentStatus"
+ }
+ }
+ },
+ "EnvironmentCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "gatewayRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "appRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ },
+ "certRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ }
+ },
+ "AppName": {
+ "type": "string"
+ },
+ "APIDefinition": {
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/APIDefinitionCurrentStatus"
+ }
+ }
+ },
+ "APIDefinitionCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "apiDefinitionVersionRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ }
+ },
+ "APIDefinitionList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/APIDefinition"
+ }
+ }
+ }
+ },
+ "APIDefinitionSpecMapping": {
+ "type": "object",
+ "additionalProperties": {
+ "anyOf": [
+ {
+ "$ref": "#/components/schemas/RESTAPISpec"
+ },
+ {
+ "$ref": "#/components/schemas/gRPCProxySpec"
+ }
+ ]
+ }
+ },
+ "RESTAPISpec": {
+ "type": "object",
+ "description": "Validates an Imported OpenAPI 3 spec formatted as JSON using the [OAS v3 schema.yaml](https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v3.0/schema.yaml) specification.\n"
+ },
+ "gRPCProxySpec": {
+ "x-f5-experimental": true,
+ "type": "object",
+ "description": "Validates an Imported gRPC spec.\n"
+ },
+ "APIDefinitionVersion": {
+ "type": "object",
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/APIDefinitionVersionMeta"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/APIDefinitionVersionDesiredState"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/APIDefinitionVersionCurrentStatus"
+ }
+ }
+ },
+ "APIDefinitionVersionList": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/APIDefinitionVersion"
+ }
+ }
+ }
+ },
+ "APIDefinitionVersionDesiredState": {
+ "type": "object",
+ "properties": {
+ "specs": {
+ "$ref": "#/components/schemas/APIDefinitionSpecMapping"
+ }
+ }
+ },
+ "APIDefinitionVersionCurrentStatus": {
+ "type": "object",
+ "properties": {
+ "specs": {
+ "$ref": "#/components/schemas/APIDefinitionSpecMapping"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "publishedApiRefs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ }
+ }
+ },
+ "apiDefinitionVersionRef": {
+ "type": "object",
+ "properties": {
+ "ref": {
+ "type": "string",
+ "description": "Reference to the Version of the API Definition.\n",
+ "example": "/services/api-definitions/baseball-stats/versions/v1"
+ },
+ "links": {
+ "$ref": "#/components/schemas/NamedLinks"
+ }
+ }
+ },
+ "APIDefinitionVersionMeta": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "isDefaultVersion": {
+ "type": "boolean"
+ }
+ }
+ }
+ ]
+ },
+ "Instance": {
+ "type": "object",
+ "description": "An NGINX Instance.",
+ "required": [
+ "metadata"
+ ],
+ "properties": {
+ "metadata": {
+ "$ref": "#/components/schemas/ResourceMeta"
+ },
+ "currentStatus": {
+ "$ref": "#/components/schemas/InstanceCurrentStatus"
+ },
+ "desiredState": {
+ "$ref": "#/components/schemas/InstanceDesiredState"
+ }
+ }
+ },
+ "GetInstanceResponse": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/Instance"
+ }
+ ]
+ },
+ "ListInstanceResponse": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Instance"
+ }
+ }
+ }
+ },
+ "InstanceRequest": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/Instance"
+ }
+ ],
+ "description": "Describes the Instance to update."
+ },
+ "InstanceDesiredState": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/OtherInstanceDesiredState"
+ },
+ {
+ "$ref": "#/components/schemas/AWSInstanceDesiredState"
+ },
+ {
+ "$ref": "#/components/schemas/AzureInstanceDesiredState"
+ },
+ {
+ "$ref": "#/components/schemas/VSphereInstanceDesiredState"
+ }
+ ],
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "OTHER_INSTANCE": "#/components/schemas/OtherInstanceDesiredState",
+ "AWS_INSTANCE": "#/components/schemas/AWSInstanceDesiredState",
+ "AZURE_INSTANCE": "#/components/schemas/AzureInstanceDesiredState",
+ "VSPHERE_INSTANCE": "#/components/schemas/VSphereInstanceDesiredState"
+ }
+ }
+ },
+ "InstanceCurrentStatus": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/OtherInstanceCurrentStatus"
+ },
+ {
+ "$ref": "#/components/schemas/AWSInstanceCurrentStatus"
+ },
+ {
+ "$ref": "#/components/schemas/AzureInstanceCurrentStatus"
+ },
+ {
+ "$ref": "#/components/schemas/VSphereInstanceCurrentStatus"
+ }
+ ],
+ "discriminator": {
+ "propertyName": "type",
+ "mapping": {
+ "OTHER_INSTANCE": "#/components/schemas/OtherInstanceCurrentStatus",
+ "AWS_INSTANCE": "#/components/schemas/AWSInstanceCurrentStatus",
+ "AZURE_INSTANCE": "#/components/schemas/AzureInstanceCurrentStatus",
+ "VSPHERE_INSTANCE": "#/components/schemas/VSphereInstanceCurrentStatus"
+ }
+ }
+ },
+ "OtherInstanceDesiredState": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "OTHER_INSTANCE is an Instance pre-installed and self-registered during NGINX installation.\n",
+ "enum": [
+ "OTHER_INSTANCE"
+ ]
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ }
+ }
+ },
+ "AWSInstanceDesiredState": {
+ "type": "object",
+ "required": [
+ "type",
+ "templateRef"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "AWS_INSTANCE is an Instance hosted in Amazon Web Services (AWS).\n",
+ "enum": [
+ "AWS_INSTANCE"
+ ]
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ }
+ }
+ },
+ "AzureInstanceDesiredState": {
+ "type": "object",
+ "required": [
+ "type",
+ "templateRef"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "AZURE_INSTANCE is an Instance hosted in Microsoft Azure.",
+ "enum": [
+ "AZURE_INSTANCE"
+ ]
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ }
+ }
+ },
+ "VSphereInstanceDesiredState": {
+ "type": "object",
+ "required": [
+ "type",
+ "templateRef"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "An Instance that resides on a VSphere host.\n",
+ "enum": [
+ "VSPHERE_INSTANCE"
+ ]
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ }
+ }
+ },
+ "OtherInstanceCurrentStatus": {
+ "type": "object",
+ "description": "Contains the current status of the Other Instance.",
+ "required": [
+ "type",
+ "hostname",
+ "version",
+ "agent",
+ "status",
+ "muted"
+ ],
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The hostname of the Instance."
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of NGINX running on the Instance."
+ },
+ "muted": {
+ "type": "boolean",
+ "description": "Indicates the status of notifications and alerts.\n- 'True' means that notifications and alerts are muted.\n- 'False' means that notifications and alerts are active.\n",
+ "deprecated": true
+ },
+ "type": {
+ "type": "string",
+ "description": "OTHER_INSTANCE is an Instance pre-installed and self-registered during NGINX installation.\n",
+ "enum": [
+ "OTHER_INSTANCE"
+ ]
+ },
+ "networkConfig": {
+ "$ref": "#/components/schemas/OtherNetworkConfig"
+ },
+ "agent": {
+ "$ref": "#/components/schemas/Agent"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ },
+ "status": {
+ "deprecated": true,
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ConfigState"
+ }
+ ]
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "legacyNginxMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacyNginxMetadata"
+ },
+ "legacySystemMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacySystemMetadata"
+ }
+ }
+ },
+ "AWSInstanceCurrentStatus": {
+ "type": "object",
+ "description": "Contains the current status of the AWS Instance.",
+ "required": [
+ "type",
+ "hostname",
+ "version",
+ "agent",
+ "muted"
+ ],
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The hostname of the Instance."
+ },
+ "instanceID": {
+ "type": "string",
+ "description": "The ID of the Instance."
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of NGINX running on the Instance."
+ },
+ "muted": {
+ "type": "boolean",
+ "description": "Indicates the status of notifications and alerts.\n- 'True' means that notifications and alerts are muted.\n- 'False' means that notifications and alerts are active.\n",
+ "deprecated": true
+ },
+ "type": {
+ "type": "string",
+ "description": "AWS_INSTANCE is an Instance hosted in Amazon Web Services (AWS).\n",
+ "enum": [
+ "AWS_INSTANCE"
+ ]
+ },
+ "networkConfig": {
+ "$ref": "#/components/schemas/AWSNetworkConfig"
+ },
+ "agent": {
+ "$ref": "#/components/schemas/Agent"
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "legacyNginxMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacyNginxMetadata"
+ },
+ "legacySystemMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacySystemMetadata"
+ }
+ }
+ },
+ "AzureInstanceCurrentStatus": {
+ "type": "object",
+ "description": "Contains the current status of the Azure Instance.",
+ "required": [
+ "type",
+ "hostname",
+ "version",
+ "agent"
+ ],
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The hostname of the Instance."
+ },
+ "instanceID": {
+ "type": "string",
+ "description": "The ID of the Instance."
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of NGINX running on the Instance."
+ },
+ "muted": {
+ "type": "boolean",
+ "description": "Indicates the mute status of notifications and alerts.\n- 'True' means that notifications and alerts are muted.\n- 'False' means that notifications and alerts are active.\n",
+ "deprecated": true
+ },
+ "type": {
+ "type": "string",
+ "description": "AZURE_INSTANCE is an Instance hosted in Microsoft Azure.",
+ "enum": [
+ "AZURE_INSTANCE"
+ ]
+ },
+ "networkConfig": {
+ "$ref": "#/components/schemas/AzureNetworkConfig"
+ },
+ "agent": {
+ "$ref": "#/components/schemas/Agent"
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "legacyNginxMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacyNginxMetadata"
+ },
+ "legacySystemMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacySystemMetadata"
+ }
+ }
+ },
+ "VSphereInstanceCurrentStatus": {
+ "type": "object",
+ "description": "Reflects the current status of the VSphere Instance.",
+ "required": [
+ "type",
+ "version",
+ "hostname",
+ "agent"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "An Instance that resides on a VSphere host.\nVSPHERE_INSTANCE is an Instance hosted in VSphere.\n",
+ "enum": [
+ "VSPHERE_INSTANCE"
+ ]
+ },
+ "hostname": {
+ "type": "string",
+ "description": "The hostname of the Instance."
+ },
+ "instanceID": {
+ "type": "string",
+ "description": "The ID of the Instance."
+ },
+ "version": {
+ "type": "string",
+ "description": "The version of NGINX running on the Instance."
+ },
+ "agent": {
+ "$ref": "#/components/schemas/Agent"
+ },
+ "templateRef": {
+ "$ref": "#/components/schemas/TemplateRef"
+ },
+ "nginx": {
+ "$ref": "#/components/schemas/Nginx"
+ },
+ "state": {
+ "$ref": "#/components/schemas/ConfigState"
+ },
+ "legacyNginxMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacyNginxMetadata"
+ },
+ "legacySystemMetadata": {
+ "deprecated": true,
+ "$ref": "#/components/schemas/LegacySystemMetadata"
+ }
+ }
+ },
+ "TemplateRef": {
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/ResourceRef"
+ }
+ ],
+ "description": "Reference to an existing Instance Template resource. This field cannot be updated."
+ },
+ "LegacySystemMetadata": {
+ "type": "object",
+ "deprecated": true,
+ "description": "Metadata that describe the operating system attributes and properties of an Instance host system. It is\nintended for internal use only and is subject to change.\n",
+ "additionalProperties": true
+ },
+ "LegacyNginxMetadata": {
+ "type": "object",
+ "deprecated": true,
+ "description": "Metadata that describe an Instance's NGINX process configuration and properties. It is intended\nfor internal use only and is subject to change.\n",
+ "additionalProperties": true
+ },
+ "Agent": {
+ "type": "object",
+ "description": "The properties of the Controller Agent running on the Instance",
+ "required": [
+ "version"
+ ],
+ "properties": {
+ "version": {
+ "type": "string",
+ "description": "The version of Controller Agent that is currently running on the Instance."
+ },
+ "online": {
+ "type": "boolean",
+ "description": "The status of Controller Agent that is currently running on the Instance."
+ },
+ "credentials": {
+ "$ref": "#/components/schemas/AgentCredentials"
+ }
+ }
+ },
+ "AgentCredentials": {
+ "type": "object",
+ "description": "The credentials of the Controller Agent running on the Instance.",
+ "properties": {
+ "hostname": {
+ "type": "string",
+ "description": "The hostname of the Agent."
+ },
+ "uuid": {
+ "type": "string",
+ "description": "The uuid of the Agent."
+ }
+ }
+ },
+ "OtherNetworkConfig": {
+ "type": "object",
+ "description": "The network config of a customer deployed Instance.",
+ "properties": {
+ "networkInterfaces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/OtherNetworkInterface"
+ }
+ }
+ }
+ },
+ "OtherNetworkInterface": {
+ "type": "object",
+ "description": "A network interface for a customer deployed Instance.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the network interface attached to the Instance."
+ },
+ "privateDnsName": {
+ "type": "string",
+ "description": "The private, internal hostname of the instance, which resolves to the Instance's private IP address.\n"
+ },
+ "privateIP": {
+ "type": "string",
+ "description": "The private IP address of the network interface."
+ },
+ "privateIPv6": {
+ "type": "string",
+ "description": "The private IPv6 address of the network interface."
+ },
+ "alternateIPList": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "alternateIPv6List": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "subnet": {
+ "type": "object",
+ "description": "The subnet that contains the interface.",
+ "properties": {
+ "cidrIPv4": {
+ "type": "string",
+ "description": "The IPv4 CIDR for the subnet."
+ },
+ "cidrIPv6": {
+ "type": "string",
+ "description": "The IPv6 CIDR for the subnet."
+ }
+ }
+ }
+ }
+ },
+ "AWSNetworkConfig": {
+ "type": "object",
+ "description": "The network config of an AWS Instance.",
+ "properties": {
+ "networkInterfaces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AWSNetworkInterface"
+ }
+ }
+ }
+ },
+ "AWSNetworkInterface": {
+ "type": "object",
+ "description": "A network interface for an AWS Instance.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the network interface attached to the Instance."
+ },
+ "privateDnsName": {
+ "type": "string",
+ "description": "The private, internal hostname of the instance, which resolves to the Instance's private IP address. \n"
+ },
+ "publicDnsName": {
+ "type": "string",
+ "description": "The public hostname of the instance, which resolves to the public IP address of the Instance. \n"
+ },
+ "privateIP": {
+ "type": "string",
+ "description": "The private IP address of the network interface."
+ },
+ "publicIP": {
+ "type": "string",
+ "description": "The public IP address of the network interface."
+ },
+ "subnet": {
+ "type": "object",
+ "description": "The subnet that contains the interface.",
+ "properties": {
+ "subnetID": {
+ "type": "string",
+ "description": "The ID of the subnet into which the instance was launched."
+ },
+ "cidrIPv4": {
+ "type": "string",
+ "description": "The IPv4 CIDR for the subnet."
+ },
+ "cidrIPv6": {
+ "type": "string",
+ "description": "The IPv6 CIDR for the subnet."
+ }
+ }
+ }
+ }
+ },
+ "AzureNetworkConfig": {
+ "type": "object",
+ "description": "The network config of an Azure Instance.",
+ "properties": {
+ "networkInterfaces": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/AzureNetworkInterface"
+ }
+ }
+ }
+ },
+ "AzureNetworkInterface": {
+ "type": "object",
+ "description": "A network interface associated with an Azure Instance.",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "The name of the network interface attached to the Instance."
+ },
+ "publicDnsName": {
+ "type": "string",
+ "description": "The public hostname of the instance, which resolves to the public IP address of the Instance. \n"
+ },
+ "privateIP": {
+ "type": "string",
+ "description": "The private IP address of the network interface."
+ },
+ "publicIP": {
+ "type": "string",
+ "description": "The public IP address of the network interface."
+ },
+ "privateIPv6": {
+ "type": "string",
+ "description": "The private IPv6 address of the network interface."
+ },
+ "publicIPv6": {
+ "type": "string",
+ "description": "The public IPv6 address of the network interface."
+ },
+ "subnet": {
+ "type": "object",
+ "description": "The subnet that contains the interface.",
+ "properties": {
+ "subnetID": {
+ "type": "string",
+ "description": "The ID of the subnet that contains the Instance."
+ },
+ "cidrIPv4": {
+ "type": "string",
+ "description": "The IPv4 CIDR for the subnet."
+ },
+ "cidrIPv6": {
+ "type": "string",
+ "description": "The IPv6 CIDR for the subnet."
+ }
+ }
+ }
+ }
+ },
+ "Nginx": {
+ "type": "object",
+ "description": "Defines properties and configuration values for Nginx.\n",
+ "properties": {
+ "process": {
+ "$ref": "#/components/schemas/NginxProcess"
+ },
+ "performance": {
+ "$ref": "#/components/schemas/Performance"
+ }
+ }
+ },
+ "NginxProcess": {
+ "type": "object",
+ "description": "Defines configuration directives that are defined in the main configuration context.\n",
+ "properties": {
+ "user": {
+ "type": "string",
+ "description": "Defines user credentials used by worker processes.\n",
+ "default": "nginx"
+ },
+ "group": {
+ "type": "string",
+ "description": "Defines group credentials used by worker processes. This will be ignored if the user\nproperty is not defined.\n",
+ "default": "nginx"
+ }
+ }
+ },
+ "Performance": {
+ "type": "object",
+ "description": "Defines performance tuning directives that are defined in the main configuration context.\n",
+ "properties": {
+ "workerProcesses": {
+ "type": "integer",
+ "description": "Defines the number of worker processes. To set it to the number of available CPU cores\nfor a system, use 0.\n",
+ "minimum": 0,
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/ngx_core_module.html#worker_processes"
+ }
+ },
+ "workerPriority": {
+ "type": "integer",
+ "description": "Defines the scheduling priority for worker processes like it is done by the nice command:\na negative number means higher priority. Allowed range normally varies from -20 to 20.\n",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/ngx_core_module.html#worker_priority"
+ }
+ },
+ "workerConnections": {
+ "type": "integer",
+ "description": "Sets the maximum number of simultaneous connections that can be opened by a worker process.\nThis number includes all the connections like proxied servers, connection with clients.\n",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/ngx_core_module.html#worker_connections"
+ }
+ },
+ "workerRlimitNofile": {
+ "type": "integer",
+ "description": "Sets the limit on the maximum number of open files for worker processes.\nUsed to increase the limit without restarting the main process.\n",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile"
+ }
+ },
+ "multiAccept": {
+ "type": "boolean",
+ "description": "Sets if the worker process will allow more than one connection at a time. If multiAccept is disabled,\nworker process only accepts one connection at a time.\n",
+ "externalDocs": {
+ "url": "https://nginx.org/en/docs/ngx_core_module.html#multi_accept"
+ }
+ }
+ }
+ },
+ "SelfLinks": {
+ "type": "object",
+ "description": "The SelfLinks object contains a link from the resource to itself.\nThis object is used only in responses.\n",
+ "properties": {
+ "rel": {
+ "type": "string",
+ "example": "/api/v1/services/environments/prod",
+ "description": "`rel` contains the complete path fragment of a URI and can be used\nto construct a query to the object.\n"
+ }
+ }
+ },
+ "ResourceMeta": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "pattern": "^[^A-Z\\s\\x00-\\x1f\\x60\\x7f\\;\\*\\\"\\[\\]\\{\\}\\\\\\/%\\?:=&\\~\\^|#<>]+$",
+ "not": {
+ "type": "string",
+ "enum": [
+ ".",
+ ".."
+ ]
+ },
+ "minLength": 1,
+ "maxLength": 1024,
+ "example": "resource-name",
+ "description": "Resource name is a unique identifier for a resource within the context of a namespace.\nResource names must conform to [RFC 1738 Section 2.2](https://www.ietf.org/rfc/rfc1738.txt) and have a valid syntax for email addresses. The following rules are enforced:\n\n- do not utilize URL encoding;\n- do not include spaces;\n- do not use uppercase characters, for example, 'A-Z'; extended character sets are supported;\n- do not use the following characters: `\"`, `*`, `:`, `;`, `/`, `\\`, `%`, `?`, `hash`, `=`, `&`, `|`, `~`, `^`, `{`, `}`, `[`, `]`, `<`, `>`;\n- cannot start or end with an `@` sign;\n- cannot be only `.` or `..`\n\nFor example: For a collection resource located at\n\n`https://controller.example.com/api/v1/services/apps/shopping_@1`\n\nthe resource name is \"shopping_@1\".\n"
+ },
+ "displayName": {
+ "type": "string",
+ "example": "My Display Name",
+ "description": "`displayName` is a user friendly resource name. It can be used to define \na longer, and less constrained, name for a resource.\n\nDisplay names:\n\n- are optional (defaults to an empty string if no value is provided),\n- do not have to be unique, \n- cannot be assigned by the server.\n"
+ },
+ "description": {
+ "type": "string",
+ "example": "This is a sample description string. It provides information about the resource.",
+ "description": "`description` is a free-form text property. You can use it to provide information that helps \nto identify the resource.\n\nDescriptions:\n\n- are optional (defaults to an empty string if no value is provided),\n- do not have to be unique, \n- cannot be assigned by the server.\n"
+ },
+ "kind": {
+ "type": "string",
+ "example": "-