From 5a15d1775b60941d069e26ee76ee29defab5614a Mon Sep 17 00:00:00 2001 From: 65397 Date: Fri, 22 Nov 2024 12:08:51 +0000 Subject: [PATCH] 5.2.0 (#72) * 20240930-01 initial branch commit * 20240930-02 dev * 20241001-01 renamed NGINX One Cloud Console into NGINX One Console * 20241001-01 renamed NGINX One Cloud Console into NGINX One Console * 20241001-01 renamed NGINX One Cloud Console into NGINX One Console * 20241024 * 20241121-01 - NGINX Plus R33 support added * 20241121-02 - NGINX Plus R33 support added * 20241121-03 - NGINX Plus R33 support added * 20241122-01 - NGINX Plus R33 support added --- .gitignore | 2 +- FEATURES.md | 80 +- README.md | 26 +- USAGE-v4.2.md | 200 - USAGE-v5.1.md | 2 +- USAGE-v5.2.md | 64 + ...NX Declarative API.postman_collection.json | 11664 +++++++++------- contrib/postman/README.md | 4 +- etc/config.toml | 4 +- ...2_CreateConfig.py => V5_2_CreateConfig.py} | 657 +- ...tion.py => V5_2_NginxConfigDeclaration.py} | 136 +- src/main.py | 70 +- src/v5_0/NGINXOneOutput.py | 4 +- src/v5_1/NGINXOneOutput.py | 4 +- src/{v4_2 => v5_2}/APIGateway.py | 17 +- src/{v4_2 => v5_2}/DeclarationPatcher.py | 6 +- src/{v4_2 => v5_2}/DevPortal.py | 12 +- src/{v4_2 => v5_2}/GitOps.py | 4 +- src/{v4_2 => v5_2}/MiscUtils.py | 18 +- src/{v4_2 => v5_2}/NAPUtils.py | 46 +- src/v5_2/NGINXOneOutput.py | 325 + src/v5_2/NGINXOneUtils.py | 32 + src/{v4_2 => v5_2}/NIMUtils.py | 4 - src/v5_2/NMSOutput.py | 331 + src/{v4_2 => v5_2}/OpenAPIParser.py | 1 - templates/v4.2/configmap.tmpl | 13 - templates/{v4.2 => v5.2}/apigateway.tmpl | 10 +- .../{v4.2 => v5.2}/authn/client/jwks.tmpl | 0 .../{v4.2 => v5.2}/authn/client/jwt.tmpl | 0 .../{v4.2 => v5.2}/authn/client/mtls.tmpl | 0 .../{v4.2 => v5.2}/authn/server/mtls.tmpl | 0 .../{v4.2 => v5.2}/authn/server/token.tmpl | 0 .../authz/client/jwt-authz-map.tmpl | 0 .../{v4.2 => v5.2}/authz/client/jwt.tmpl | 0 templates/v5.2/devportal/backstage.tmpl | 17 + templates/{v4.2 => v5.2}/http.tmpl | 29 +- templates/{v4.2 => v5.2}/logformat.tmpl | 0 templates/v5.2/misc/resolver.tmpl | 4 + templates/v5.2/misc/upstream-http.tmpl | 23 + templates/v5.2/misc/upstream-stream.tmpl | 19 + templates/v5.2/nginx-conf/license-key.tmpl | 1 + .../{v4.2 => v5.2}/nginx-conf/mime.types | 0 .../{v4.2 => v5.2}/nginx-conf/nginx.conf | 21 +- templates/{v4.2 => v5.2}/stream.tmpl | 19 +- templates/v5.2/visibility/moesif/http.tmpl | 14 + templates/v5.2/visibility/moesif/server.tmpl | 21 + 46 files changed, 8420 insertions(+), 5484 deletions(-) delete mode 100644 USAGE-v4.2.md create mode 100644 USAGE-v5.2.md rename src/{V4_2_CreateConfig.py => V5_2_CreateConfig.py} (54%) rename src/{V4_2_NginxConfigDeclaration.py => V5_2_NginxConfigDeclaration.py} (85%) rename src/{v4_2 => v5_2}/APIGateway.py (73%) rename src/{v4_2 => v5_2}/DeclarationPatcher.py (97%) rename src/{v4_2 => v5_2}/DevPortal.py (84%) rename src/{v4_2 => v5_2}/GitOps.py (97%) rename src/{v4_2 => v5_2}/MiscUtils.py (78%) rename src/{v4_2 => v5_2}/NAPUtils.py (89%) create mode 100644 src/v5_2/NGINXOneOutput.py create mode 100644 src/v5_2/NGINXOneUtils.py rename src/{v4_2 => v5_2}/NIMUtils.py (90%) create mode 100644 src/v5_2/NMSOutput.py rename src/{v4_2 => v5_2}/OpenAPIParser.py (95%) delete mode 100644 templates/v4.2/configmap.tmpl rename templates/{v4.2 => v5.2}/apigateway.tmpl (94%) rename templates/{v4.2 => v5.2}/authn/client/jwks.tmpl (100%) rename templates/{v4.2 => v5.2}/authn/client/jwt.tmpl (100%) rename templates/{v4.2 => v5.2}/authn/client/mtls.tmpl (100%) rename templates/{v4.2 => v5.2}/authn/server/mtls.tmpl (100%) rename templates/{v4.2 => v5.2}/authn/server/token.tmpl (100%) rename templates/{v4.2 => v5.2}/authz/client/jwt-authz-map.tmpl (100%) rename templates/{v4.2 => v5.2}/authz/client/jwt.tmpl (100%) create mode 100644 templates/v5.2/devportal/backstage.tmpl rename templates/{v4.2 => v5.2}/http.tmpl (93%) rename templates/{v4.2 => v5.2}/logformat.tmpl (100%) create mode 100644 templates/v5.2/misc/resolver.tmpl create mode 100644 templates/v5.2/misc/upstream-http.tmpl create mode 100644 templates/v5.2/misc/upstream-stream.tmpl create mode 100644 templates/v5.2/nginx-conf/license-key.tmpl rename templates/{v4.2 => v5.2}/nginx-conf/mime.types (100%) rename templates/{v4.2 => v5.2}/nginx-conf/nginx.conf (58%) rename templates/{v4.2 => v5.2}/stream.tmpl (69%) create mode 100644 templates/v5.2/visibility/moesif/http.tmpl create mode 100644 templates/v5.2/visibility/moesif/server.tmpl diff --git a/.gitignore b/.gitignore index 4d704b9..9fa72da 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,9 @@ Thumbs.db ======= /.idea/ /src/__pycache__/ -/src/v4_2/__pycache__/ /src/v5_0/__pycache__/ /src/v5_1/__pycache__/ +/src/v5_2/__pycache__/ /contrib/devportal/redocly/src/__pycache__/ /contrib/app-protect/src/__pycache__/ /venv/ diff --git a/FEATURES.md b/FEATURES.md index 995bcb9..3562682 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -4,15 +4,15 @@ NGINX Declarative API has been tested with the following NGINX control plane releases: -| Control plane | API v4.2 | API v5.0 | API v5.1 | Notes | -|--------------------------|----------|--------------|----------------------|---------------| -| NGINX Instance Manager | 2.14+ | 2.14+ | 2.16+ | | -| NGINX One Cloud Console | | Early access | General Availability | | +| Control plane | API v5.0 | API v5.1 | API v5.2 | Notes | +|------------------------|--------------|----------------------|----------------------|-------| +| NGINX Instance Manager | 2.14+ | 2.16+ | 2.18+ | | +| NGINX One Console | Early access | General Availability | General availability | | ### NGINX `http` and `stream` servers -| Feature | API v4.2 | API v5.0 | API v5.1 | Notes | +| Feature | API v5.0 | API v5.1 | API v5.2 | Notes | |----------------------------|----------|----------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Upstreams | X | X | X |
  • Snippets supported: static and from source of truth
  • | | HTTP servers | X | X | X |
  • Snippets supported (`http`, `servers`, `locations`): static and from source of truth
  • | @@ -40,15 +40,15 @@ Locations `.declaration.http.servers[].locations[].uri` match modifiers in `.dec ### NGINX API Gateway use case -| Feature | API v4.2 | API v5.0 | API v5.1 | Notes | -|----------------------------------------------|------------------|------------------------------------|-------------------------------------------------------------------------------|-----------------------------------------| -| Configuration generation from OpenAPI schema | X | X | X | | -| HTTP methods enforcement | X | X | X | | -| per-URI rate limiting | X | X | X | | -| per-URI client authentication | X | X |
  • Static JWT key
  • JWT key fetched from URL
  • Bearer token
  • | | -| per-URI client authorization | X | X |
  • JWT claims
  • | | -| Developer portal |
  • Redocly
  • |
  • Redocly
  • Backstage
  • |
  • Redocly
  • Backstage
  • | Supported through 3rd party integration | -| API visibility | | |
  • Moesif
  • | Supported through 3rd party integration | +| Feature | API v5.0 | API v5.1 | API v5.2 | Notes | +|----------------------------------------------|------------------------------------|-------------------------------------------------------------------------------|-------------------------------------------------------------------------------|-----------------------------------------| +| Configuration generation from OpenAPI schema | X | X | X | | +| HTTP methods enforcement | X | X | X | | +| per-URI rate limiting | X | X | X | | +| per-URI client authentication | X |
  • Static JWT key
  • JWT key fetched from URL
  • Bearer token
  • |
  • Static JWT key
  • JWT key fetched from URL
  • Bearer token
  • | | +| per-URI client authorization | X |
  • JWT claims
  • |
  • JWT claims
  • | | +| Developer portal |
  • Redocly
  • Backstage
  • |
  • Redocly
  • Backstage
  • |
  • Redocly
  • Backstage
  • | Supported through 3rd party integration | +| API visibility | |
  • Moesif
  • |
  • Moesif
  • | Supported through 3rd party integration | Swagger files and OpenAPI schemas can be used to automatically configure NGINX as an API Gateway @@ -81,24 +81,24 @@ See the [Postman collection](/contrib/) for usage examples ### NGINX API Gateway use case - Developer Portal -| Type | API v4.2 | API v5.0 | API v5.1 | Notes | -|---------------|----------|-----------|----------|------------------------------------------| -| Redocly | X | X | X | Developer portal published by NGINX Plus | -| Backstage.io | | X | X | Backstage YAML manifest generated | +| Type | API v5.0 | API v5.1 | API v5.2 | Notes | +|---------------|-----------|----------|----------|------------------------------------------| +| Redocly | X | X | X | Developer portal published by NGINX Plus | +| Backstage.io | X | X | X | Backstage YAML manifest generated | ### NGINX API Gateway use case - Visibility -| Type | API v4.2 | API v5.0 | API v5.1 | Notes | +| Type | API v5.0 | API v5.1 | API v5.2 | Notes | |--------------|----------|----------|----------|-----------------------------------------------------------------------------------------------| -| Moesif | | | X | Integration with Moesif - see https://www.moesif.com/docs/server-integration/nginx-openresty/ | +| Moesif | | X | X | Integration with Moesif - see https://www.moesif.com/docs/server-integration/nginx-openresty/ | ### Client authentication -| Type | Description | API v4.2 | API v5.0 | API v5.1 | Notes | -|------|----------------------|----------|----------|-------------------------------------|-------------------------------------| -| jwt | Java Web Token (JWT) | X | X | X | | -| mtls | Mutual TLS | X | X |
  • Supported for HTTP servers
  • |
  • Supported for HTTP servers
  • | +| Type | Description | API v5.0 | API v5.1 | API v5.2 | Notes | +|------|----------------------|----------|----------|----------|-------------------------------------| +| jwt | Java Web Token (JWT) | X | X | X | | +| mtls | Mutual TLS | X | X | X |
  • Supported for HTTP servers
  • | #### Examples @@ -144,7 +144,7 @@ Client-side authentication profiles to be defined under `.declaration.http.authe ### Client authorization -| Type | Description | API v4.2 | API v5.0 | API v5.1 | Notes | +| Type | Description | API v5.0 | API v5.1 | API v5.2 | Notes | |------|----------------------|----------|----------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | jwt | Java Web Token (JWT) | X | X | X | Based on JWT claims. Supported under
  • .declaration.http.servers[]
  • .declaration.http.servers[].location[]
  • .declaration.http.servers[].location[].apigateway
  • | @@ -174,12 +174,12 @@ Client-side authorization profiles to be defined under `.declaration.http.author ### Upstream and Source of truth authentication -| Type | Description | API v4.2 | API v5.0 | API v5.1 | Notes | -|--------------|----------------------------------------------|----------|----------|----------|----------------------------------------------------------------------------------------| +| Type | Description | API v5.0 | API v5.1 | API v5.2 | Notes | +|--------------|----------------------------------------------|----------|----------|----------|--------------------------------------------------------------------------------| | Bearer token | Authentication token as Authorization Bearer | X | X | X | `Bearer` Authorization header is injected in requests to upstreams and source of truth | -| Basic Auth | Authentication token as Authorization Basic | X | X | X | `Basic` Authorization header is injected in requests to upstreams and source of truth | -| HTTP header | Authentication token in custom HTTP header | X | X | X | HTTP header is injected in requests to upstreams and source of truth | -| mTLS | Mutual TLS | X | X | X | Client certificate is sent to upstream / source of truth | +| Basic Auth | Authentication token as Authorization Basic | X | X | X | `Basic` Authorization header is injected in requests to upstreams and source of truth | +| HTTP header | Authentication token in custom HTTP header | X | X | X | HTTP header is injected in requests to upstreams and source of truth | +| mTLS | Mutual TLS | X | X | X | Client certificate is sent to upstream / source of truth | #### Examples @@ -242,8 +242,8 @@ Server-side authentication profiles to be defined under `.declaration.http.authe ### HTTP Headers manipulation -| Type | API v4.2 | API v5.0 | API v5.1 | Notes | -|-----------------------------|----------|----------|----------|------------------------------------------------------------------------------------------------------------------------------| +| Type | API v5.0 | API v5.1 | API v5.2 | Notes | +|-----------------------------|----------|----------|----------|---------------------------------------------------------------------------------------------------------------------| | Request (client to server) | X | X | X |
  • `set` - new header injection
  • `delete` - client header removal
  • | | Response (server to client) | X | X | X |
  • `add` - new header injection
  • `delete` - server header removal
  • `replace` - server header replacement
  • | @@ -291,12 +291,12 @@ To be defined under `.declaration.http.servers[].headers` and/or `.declaration.h ### NGINX Javascript -| Hook type | API v4.2 | API v5.0 | API v5.1 | Notes | -|-------------------|----------|----------|----------|------------------------------------------------------------------------------------------------------------------------------| +| Hook type | API v5.0 | API v5.1 | API v5.2 | Notes | +|-------------------|----------|----------|----------|---------------------------------------------------------------------------------------------------------------------| | js_body_filter | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | -| js_content | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | -| js_header_filter | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | -| js_periodic | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | +| js_content | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | +| js_header_filter | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | +| js_periodic | X | X | X | Available in
  • `declaration.http.servers[].location[]`
  • | | js_preload_object | X | X | X | Available in
  • `.declaration.http`
  • `declaration.http.servers[]`
  • `declaration.http.servers[].location[]`
  • | | js_set | X | X | X | Available in
  • `.declaration.http`
  • `declaration.http.servers[]`
  • `declaration.http.servers[].location[]`
  • | @@ -444,9 +444,9 @@ Example hooks: ### DNS resolvers -| | API v4.2 | API v5.0 | API v5.1 | Notes | -|-----------------------|----------|----------|----------|------------------------------------------------------------------------------------------------------------------------------------| -| DNS resolver profiles | | | X | Available in
  • `declaration.http.servers[]`
  • `declaration.http.upstreams[]`
  • `declaration.layer4.upstreams[]`
  • | +| | API v5.0 | API v5.1 | API v5.2 | Notes | +|-----------------------|----------|----------|----------|---------------------------------------------------------------------------------------------------------------------------| +| DNS resolver profiles | | X | X | Available in
  • `declaration.http.servers[]`
  • `declaration.http.upstreams[]`
  • `declaration.layer4.upstreams[]`
  • | #### Examples diff --git a/README.md b/README.md index 56c9cc4..bcc93f2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) -This project provides a set of declarative REST API for [NGINX Instance Manager](https://docs.nginx.com/nginx-management-suite/nim/) and [NGINX One Cloud Console](https://docs.nginx.com/nginx-one/) +This project provides a set of declarative REST API for [NGINX Instance Manager](https://docs.nginx.com/nginx-management-suite/nim/) and [NGINX One Console](https://docs.nginx.com/nginx-one/) It can be used to manage NGINX Plus configuration lifecycle and to create NGINX Plus configurations using JSON service definitions. @@ -10,7 +10,7 @@ GitOps integration is supported: source of truth is checked for updates (NGINX A Use cases include: -- Integration with NGINX Instance Manager (instance group) and NGINX One Cloud Console (config sync group) +- Integration with NGINX Instance Manager (instance group) and NGINX One Console (config sync group) - NGINX App Protect DevSecOps integration (NGINX Instance Manager only) - API Gateway deployments with automated Swagger / OpenAPI schema import - API Developer portals zero-touch deployment (redocly and backstage supported) @@ -28,10 +28,12 @@ A **blog article** to automate NGINX API Gateway management from OpenAPI schemas ## Supported releases -- NGINX Instance Manager 2.14+ -- NGINX One Cloud Console -- NGINX Plus R30+ -- NGINX App Protect WAF 4 and 5 +- [NGINX Instance Manager 2.14+](https://docs.nginx.com/nginx-management-suite/nim/) +- [NGINX One Console](https://docs.nginx.com/nginx-one/) +- [NGINX Plus R30+](https://docs.nginx.com/nginx/) +- NGINX App Protect WAF [4](https://docs.nginx.com/nginx-app-protect-waf/v4/) and [5](https://docs.nginx.com/nginx-app-protect-waf/v5/) + +**Note**: NGINX Plus R33 and above [require a valid license](https://docs.nginx.com/solutions/about-subscription-licenses/) and the `.output.license` section in the declarative JSON is required. See the [usage notes](/USAGE-v5.2.md) for further details. [Postman collection](/contrib/postman) examples are provided for R33. ## Architecture @@ -44,7 +46,7 @@ stateDiagram-v2 Client: REST Client Pipeline: CI/CD Pipeline NIM: NGINX Instance Manager - N1: NGINX One Cloud Console + N1: NGINX One Console AGENT1: NGINX Agent NGINX1: NGINX AGENT2: NGINX Agent @@ -90,7 +92,7 @@ participant Source of Truth participant NGINX Declarative API Core participant Redis participant Developer Portal Service -participant NGINX Instance Manager / NGINX One +participant NGINX Instance Manager / NGINX One Console participant NGINX box NGINX Declarative API @@ -135,7 +137,7 @@ end ## Output formats - [X] Output to NGINX Instance Manager 2.14+ imperative REST API (instance group) -- [X] Output to NGINX One Cloud Console REST API (config sync group) +- [X] Output to NGINX One Console REST API (config sync group) ## Supported features @@ -145,9 +147,9 @@ See the [features list](/FEATURES.md) Usage details and JSON schema are available here: -- [API v5.1](/USAGE-v5.1.md) - latest -- [API v5.0](/USAGE-v5.0.md) -- [API v4.2](/USAGE-v4.2.md) - deprecated +- [API v5.2](/USAGE-v5.2.md) - latest - required for NGINX Plus R33+ +- [API v5.1](/USAGE-v5.1.md) +- [API v5.0](/USAGE-v5.0.md) - deprecated A sample Postman collection and usage instructions can be found [here](/contrib/postman) diff --git a/USAGE-v4.2.md b/USAGE-v4.2.md deleted file mode 100644 index f5b5281..0000000 --- a/USAGE-v4.2.md +++ /dev/null @@ -1,200 +0,0 @@ -# Usage for API v4.2 - -Version 4.2 API requires: - -- NGINX Instance Manager 2.14+ -- NGINX Plus R30+ - -If NGINX App Protect declarations are used: -- NGINX App Protect Policy Compiler 4.2.0+ -- NGINX Plus instances running App Protect WAF 4.2.0+ using `precompiled_publication: true` in `/etc/nginx-agent/nginx-agent.conf` - -The JSON schema is self explanatory. See also the [sample Postman collection](/contrib/postman) - -- `.output.type` defines how NGINX configuration will be returned: - - *plaintext* - plaintext format - - *json* - JSON-wrapped, base64-encoded - - *configmap* - Kubernetes Configmap in YAML format. - - `.output.configmap.name` must be set to the ConfigMap name - - `.output.configmap.filename` must be set to the NGINX configuration filename - - `.output.configmap.namespace` the optional namespace for the ConfigMap - - *http* - NGINX configuration is POSTed to custom url - - `.output.http.url` the URL to POST the configuration to - - *nms* - NGINX configuration is published as a Staged Config to NGINX Instance Manager - - `.output.nms.url` the NGINX Instance Manager URL - - `.output.nms.username` the NGINX Instance Manager authentication username - - `.output.nms.password` the NGINX Instance Manager authentication password - - `.output.nms.instancegroup` the NGINX Instance Manager instance group to publish the configuration to - - `.output.nms.synctime` **optional**, used for GitOps autosync. When specified and the declaration includes HTTP(S) references to NGINX App Protect policies, TLS certificates/keys/chains, the HTTP(S) endpoints will be checked every `synctime` seconds and if external contents have changed, the updated configuration will automatically be published to NGINX Instance Manager - - `.output.nms.modules` an optional array of NGINX module names (ie. 'ngx_http_app_protect_module', 'ngx_http_js_module','ngx_stream_js_module') - - `.output.nms.certificates` an optional array of TLS certificates/keys/chains to be published - - `.output.nms.certificates[].type` the item type ('certificate', 'key', 'chain') - - `.output.nms.certificates[].name` the certificate/key/chain name with no path/extension (ie. 'test-application') - - `.output.nms.certificates[].contents` the content: this can be either base64-encoded or be a HTTP(S) URL that will be fetched dynamically from a source of truth - - `.output.nms.policies[]` an optional array of NGINX App Protect security policies - - `.output.nms.policies[].type` the policy type ('app_protect') - - `.output.nms.policies[].name` the policy name (ie. 'prod-policy') - - `.output.nms.policies[].active_tag` the policy tag to enable among all available versions (ie. 'v1') - - `.output.nms.policies[].versions[]` array with all available policy versions - - `.output.nms.policies[].versions[].tag` the policy version's tag name - - `.output.nms.policies[].versions[].displayName` the policy version's display name - - `.output.nms.policies[].versions[].description` the policy version's description - - `.output.nms.policies[].versions[].contents` this can be either base64-encoded or be a HTTP(S) URL that will be fetched dynamically from a source of truth -- `.declaration` describes the NGINX configuration to be created. - -### Locations ### - -Locations `.declaration.http.servers[].locations[].uri` match modifiers in `.declaration.http.servers[].locations[].urimatch` can be: - -- *prefix* - prefix URI matching -- *exact* - exact URI matching -- *regex* - case sensitive regex matching -- *iregex* - case insensitive regex matching -- *best* - case sensitive regex matching that halts any other location matching once a match is made - -### Javascript profiles ### - -NGINX Javascript profiles are defined in `.declaration.http.njs[]`: - -- `name` - the NJS profile name -- `file.content` - the base64-encoded njs source code or the `http(s)://` URL of the file -- `file.authentication.server[0].profile` - authentication profile name if `file.content` is a URL and the request must be authenticated - -### Javascript hooks ### - -NGINX Javascript hooks can be used in: - -- `.declaration.http.njs` - - Supported hooks: - - `js_preload_object' - - 'js_set` -- `.declaration.http.server[].njs` - - Supported hooks: - - `js_preload_object' - - 'js_set` -- `.declaration.http.server[].location[].njs` - - Supported hooks: - - `js_body_filter' - - 'js_content' - - 'js_header_filter' - - 'js_periodic' - - 'js_preload_object' - - 'js_set` - -Hooks invocation is: - -``` -"njs": [ - { - "hook": { - "name": "", - "parameters": [ - { - "name": "", - "value": "" - } - ] - }, - "profile": "", - "function": "" - } -] -``` - -For detailed examples see the [Postman collection](/contrib/postman) - -### API Gateway ### - -Swagger files and OpenAPI schemas can be used to automatically configure NGINX as an API Gateway. Developer portal creation is supported through [Redocly](https://redocly.com/) - -Declaration path `.declaration.http.servers[].locations[].apigateway` defines the API Gateway configuration: - -- `openapi_schema` - the base64-encoded schema, or the schema URL. YAML and JSON are supported -- `api_gateway.enabled` - enable/disable API Gateway provisioning -- `api_gateway.strip_uri` - removes the `.declaration.http.servers[].locations[].uri` part of the URI before forwarding requests to the upstream -- `api_gateway.server_url` - the base URL of the upstream server -- `developer_portal.enabled` - enable/disable Developer portal provisioning -- `developer_portal.uri` - the trailing part of the Developer portal URI, this is appended to `.declaration.http.servers[].locations[].uri`. If omitted it defaults to `devportal.html` -- `authentication` - optional, used to enforce authentication at the API Gateway level -- `authentication.client[]` - authentication profile names -- `authentication.enforceOnPaths` - if set to `true` authentication is enforced on all API endpoints listed under `authentication.paths`. if set to `false` authentication is enforced on all API endpoints but those listed under `authentication.paths` -- `authentication.paths` - paths to enforce authentication -- `authorization[]` - optional, used to enforce authorization -- `authorization[].profile` - authorization profile name -- `authorization[].enforceOnPaths` - if set to `true` authorization is enforced on all API endpoints listed under `authorization.paths`. if set to `false` authorization is enforced on all API endpoints but those listed under `authorization[].paths` -- `authorization[].paths` - paths to enforce authorization -- `rate_limit` - optional, used to enforce rate limiting at the API Gateway level -- `rate_limit.enforceOnPaths` - if set to `true` rate limiting is enforced on all API endpoints listed under `rate_limit.paths`. if set to `false` rate limiting is enforced on all API endpoints but those listed under `rate_limit.paths` - -A sample API Gateway declaration to publish the `https://petstore.swagger.io` REST API and enforce: - -- REST API endpoint URIs -- HTTP Methods -- Rate limiting on `/user/login`, `/usr/logout` and `/pet/{petId}/uploadImage` -- JWT authentication on `/user/login`, `/usr/logout` and `/pet/{petId}/uploadImage` -- JWT claim-based authorization on `/user/login`, `/usr/logout` and `/pet/{petId}/uploadImage` - -can be found in the [Postman collection](/contrib/) - -### Maps ### - -Map entries `.declaration.maps[].entries.keymatch` can be: - -- *exact* - exact variable matching -- *regex* - case sensitive regex matching -- *iregex* - case insensitive regex matching - -### Snippets ### - -Snippets for `http`, `upstream`, `server` and `location` can be specified as: -- base64-encoded content -- HTTP(S) URL of a source of truth to fetch snippet content from. Content on the source of truth must be plaintext -- source of truth authentication is supported through authentication profiles - -### Authentication profiles ### - -Client and Server authentication profiles can be defined in the declarative json at `.declaration.http.authentication` - -```commandline - "authentication": { - "client": [ - { - "name": "", - "type": "", - "": { - "": "", - [...] - } - }, - [...] - ], - "server": [ - { - "name": "", - "type": "", - "": { - "": "", - [...] - } - }, - [...] - ] -``` - -For a list of all supported authentication profile types see the [feature matrix](/FEATURES.md) - -### API endpoints ### - -- `POST /v4.2/config/` - Publish a new declaration -- `PATCH /v4.2/config/{config_uid}` - Update an existing declaration - - Per-HTTP server CRUD - - Per-HTTP upstream CRUD - - Per-Stream server CRUD - - Per-Stream upstream CRUD - - Per-NGINX App Protect WAF policy CRUD -- `GET /v4.2/config/{config_uid}` - Retrieve an existing declaration -- `DELETE /v4.2/config/{config_uid}` - Delete an existing declaration - -### Usage Examples ### - -A sample Postman collection is available [here](/contrib/postman) \ No newline at end of file diff --git a/USAGE-v5.1.md b/USAGE-v5.1.md index 546c834..64370df 100644 --- a/USAGE-v5.1.md +++ b/USAGE-v5.1.md @@ -4,7 +4,7 @@ Version 5.1 supports: - [NGINX Instance Manager](https://docs.nginx.com/nginx-management-suite/nim/) 2.14+ - [NGINX One Cloud Console](https://docs.nginx.com/nginx-one/) -- [NGINX Plus](https://docs.nginx.com/nginx/) R30+ +- [NGINX Plus](https://docs.nginx.com/nginx/) R30, R31, R32 - [NGINX App Protect WAF](https://docs.nginx.com/nginx-app-protect-waf/) 4 with precompiled [policy bundles](https://docs.nginx.com/nginx-app-protect-waf/v5/admin-guide/compiler/) The JSON schema is self explanatory. See also the [sample Postman collection](/contrib/postman) for usage examples diff --git a/USAGE-v5.2.md b/USAGE-v5.2.md new file mode 100644 index 0000000..00163ab --- /dev/null +++ b/USAGE-v5.2.md @@ -0,0 +1,64 @@ +# Usage for NGINX Declarative API v5.2 + +Version 5.2 supports: + +- [NGINX Instance Manager](https://docs.nginx.com/nginx-management-suite/nim/) 2.14+. Version 2.18+ is required for NGINX R33 and above +- [NGINX One Console](https://docs.nginx.com/nginx-one/) +- [NGINX Plus](https://docs.nginx.com/nginx/) R31, R32, R33+ +- [NGINX App Protect WAF](https://docs.nginx.com/nginx-app-protect-waf/) 4 with precompiled [policy bundles](https://docs.nginx.com/nginx-app-protect-waf/v5/admin-guide/compiler/) + +The JSON schema is self explanatory. See also the [sample Postman collection](/contrib/postman) for usage examples + +- `.output.license` defines the JWT license to use for NGINX Plus R33+ + - `.output.license.endpoint` the usage reporting endpoint (defaults to `product.connect.nginx.com`). NGINX Instance Manager address can be used here + - `.output.license.token` the JWT license token + - `.output.license.ssl_verify` set to `false` to trust all SSL certificates (not recommended). Useful for reporting to NGINX Instance Manager without a local PKI. + - `.output.license.grace_period` Set to 'true' to begin the 180-day reporting enforcement grace period. Reporting must begin or resume before the end of the grace period to ensure continued operation +- `.output.type` defines how NGINX configuration will be returned: + - *nms* - NGINX configuration is published as a Staged Config to NGINX Instance Manager + - `.output.nms.url` the NGINX Instance Manager URL + - `.output.nms.username` the NGINX Instance Manager authentication username + - `.output.nms.password` the NGINX Instance Manager authentication password + - `.output.nms.instancegroup` the NGINX Instance Manager instance group to publish the configuration to + - `.output.nms.synctime` **optional**, used for GitOps autosync. When specified and the declaration includes HTTP(S) references to NGINX App Protect policies, TLS certificates/keys/chains, the HTTP(S) endpoints will be checked every `synctime` seconds and if external contents have changed, the updated configuration will automatically be published to NGINX Instance Manager + - `.output.nms.modules` an optional array of NGINX module names (ie. 'ngx_http_app_protect_module', 'ngx_http_js_module','ngx_stream_js_module') + - `.output.nms.certificates` an optional array of TLS certificates/keys/chains to be published + - `.output.nms.certificates[].type` the item type ('certificate', 'key', 'chain') + - `.output.nms.certificates[].name` the certificate/key/chain name with no path/extension (ie. 'test-application') + - `.output.nms.certificates[].contents` the content: this can be either base64-encoded or be a HTTP(S) URL that will be fetched dynamically from a source of truth + - `.output.nms.policies[]` an optional array of NGINX App Protect security policies + - `.output.nms.policies[].type` the policy type ('app_protect') + - `.output.nms.policies[].name` the policy name (ie. 'prod-policy') + - `.output.nms.policies[].active_tag` the policy tag to enable among all available versions (ie. 'v1') + - `.output.nms.policies[].versions[]` array with all available policy versions + - `.output.nms.policies[].versions[].tag` the policy version's tag name + - `.output.nms.policies[].versions[].displayName` the policy version's display name + - `.output.nms.policies[].versions[].description` the policy version's description + - `.output.nms.policies[].versions[].contents` this can be either base64-encoded or be a HTTP(S) URL that will be fetched dynamically from a source of truth + - *nginxone* - NGINX configuration is published to a NGINX One Console config sync group + - `.output.nginxone.url` the NGINX One Console URL + - `.output.nginxone.namespace` the NGINX One Console namespace + - `.output.nginxone.token` the authentication token + - `.output.nginxone.configsyncgroup` the NGINX One Console config sync group name + - `.output.nginxone.synctime` **optional**, used for GitOps autosync. When specified and the declaration includes HTTP(S) references to NGINX App Protect policies, TLS certificates/keys/chains, the HTTP(S) endpoints will be checked every `synctime` seconds and if external contents have changed, the updated configuration will automatically be published to NGINX One Cloud Console + - `.output.nginxone.modules` an optional array of NGINX module names (ie. 'ngx_http_app_protect_module', 'ngx_http_js_module','ngx_stream_js_module') + - `.output.nginxone.certificates` an optional array of TLS certificates/keys/chains to be published + - `.output.nginxone.certificates[].type` the item type ('certificate', 'key', 'chain') + - `.output.nginxone.certificates[].name` the certificate/key/chain name with no path/extension (ie. 'test-application') + - `.output.nginxone.certificates[].contents` the content: this can be either base64-encoded or be a HTTP(S) URL that will be fetched dynamically from a source of truth +- `.declaration` describes the NGINX configuration to be created + - `.declaration.http[]` NGINX HTTP definitions + - `.declaration.layer4[]` NGINX TCP/UDP definitions + - `.declaration.resolvers[]` DNS resolvers definitions + +### API endpoints + +- `POST /v5.2/config/` - Publish a new declaration +- `PATCH /v5.2/config/{config_uid}` - Update an existing declaration + - Per-HTTP server CRUD + - Per-HTTP upstream CRUD + - Per-Stream server CRUD + - Per-Stream upstream CRUD + - Per-NGINX App Protect WAF policy CRUD +- `GET /v5.2/config/{config_uid}` - Retrieve an existing declaration +- `DELETE /v5.2/config/{config_uid}` - Delete an existing declaration \ No newline at end of file diff --git a/contrib/postman/NGINX Declarative API.postman_collection.json b/contrib/postman/NGINX Declarative API.postman_collection.json index e1d68ed..1b6c5a0 100644 --- a/contrib/postman/NGINX Declarative API.postman_collection.json +++ b/contrib/postman/NGINX Declarative API.postman_collection.json @@ -1,14 +1,15 @@ { "info": { - "_postman_id": "4ba43073-b4a2-4e07-9da7-bc252c90a1cd", + "_postman_id": "3abdf170-33d5-4502-b81b-97d8f9c315e4", "name": "NGINX Declarative API", - "description": "Declarative REST API and GitOps automation layer for NGINX Instance Manager and NGINX One\n\n[https://github.com/f5devcentral/NGINX-Declarative-API/](https://github.com/f5devcentral/NGINX-Declarative-API/)", + "description": "Declarative REST API and GitOps automation layer for NGINX Instance Manager and NGINX One Console\n\n[https://github.com/f5devcentral/NGINX-Declarative-API/](https://github.com/f5devcentral/NGINX-Declarative-API/)", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "30973250" + "_exporter_id": "1667416", + "_collection_link": "https://orange-rocket-1353.postman.co/workspace/NGINX-Declarative-API~8ba6e9c1-a04b-4484-8193-bbb142560553/collection/1667416-3abdf170-33d5-4502-b81b-97d8f9c315e4?action=share&source=collection_link&creator=1667416" }, "item": [ { - "name": "v4.2", + "name": "v5.0", "item": [ { "name": "Configuration generation", @@ -352,183 +353,692 @@ "name": "Declarative automation examples", "item": [ { - "name": "API Gateway", + "name": "NGINX Instance Manager", "item": [ { - "name": "Ergast API", + "name": "API Gateway", "item": [ { - "name": "Ergast API Gateway and DevPortal", - "event": [ + "name": "Ergast API", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/ergast-devportal.html\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Ergast API Gateway and DevPortal with redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Petstore API", - "item": [ - { - "name": "Petstore API Gateway RateLimit", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"name\": \"Petstore API Gateway\",\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Ergast API Gateway and DevPortal with backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\" \n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF", - "event": [ + "name": "Petstore API", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Petstore API Gateway RateLimit", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Petstore & Ergast API Gateway all in one", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore and Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"192.168.2.13\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n },\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/ergast-devportal.html\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"ergast_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"ergast_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n },\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "CRUD automation", + "item": [ + { + "name": "Create initial NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Update HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Modify and add HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Modify and add HTTP server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server_v2.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_v2_log\",\n \"error\": \"/var/log/nginx/error_v2_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream_added\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.100:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"192.168.1.101:80\"\n },\n {\n \"server\": \"192.168.1.102:80\"\n },\n {\n \"server\": \"192.168.1.103:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove HTTP server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Modify Stream server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", "protocol": "http", "host": [ "{{ncg_host}}" @@ -536,2458 +1046,2933 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config" + "config", + "{{configUid}}" ] } }, "response": [] - } - ] - }, - { - "name": "Petstore & Ergast API Gateway all in one", - "event": [ + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore and Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"192.168.2.13\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n },\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/ergast-devportal.html\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"ergast_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"ergast_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n },\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Add stream server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "CRUD automation", - "item": [ - { - "name": "Create initial NGINX configuration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Update HTTP upstream", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Remove stream server and upstream #1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Modify and add HTTP upstream", - "event": [ + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Remove stream server and upstream #2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Modify and add HTTP server and upstream", - "event": [ + "name": "GitOps autosync", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server_v2.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_v2_log\",\n \"error\": \"/var/log/nginx/error_v2_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream_added\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.100:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"192.168.1.101:80\"\n },\n {\n \"server\": \"192.168.1.102:80\"\n },\n {\n \"server\": \"192.168.1.103:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "NGINX Plus and GitOps", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Remove HTTP server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "NGINX App Protect WAF and GitOps", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Modify Stream server and upstream", - "event": [ + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_app_protect_module\",\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"gitops\",\n \"versions\": [\n {\n \"tag\": \"gitops\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/nap-policy-gitops.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Add stream server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Remove stream server and upstream #1", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Get declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Remove stream server and upstream #2", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "GitOps autosync", - "item": [ - { - "name": "NGINX Plus and GitOps", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Delete declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "NGINX App Protect WAF and GitOps", - "event": [ + "name": "Housekeeping - common endpoints", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_app_protect_module\",\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"gitops\",\n \"versions\": [\n {\n \"tag\": \"gitops\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/nap-policy-gitops.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Clean NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Get declaration status", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}", - "status" - ] - } - }, - "response": [] - }, - { - "name": "Get declaration", - "event": [ + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "Get declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "Delete declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Delete declaration", - "event": [ + "name": "HTTP Headers Manipulation", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "Create test echo service", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } } - } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "Manipulate headers - server level", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Housekeeping - common endpoints", - "item": [ - { - "name": "Clean NGINX configuration", - "event": [ + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\"\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Manipulate headers - location level", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + }, + "response": [] } - }, - "response": [] + ], + "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" }, { - "name": "Get declaration status", - "event": [ + "name": "HTTPS server", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "TLS Offload", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "TLS Offload and NGINX App Protect", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}", - "status" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Get declaration", - "event": [ + "name": "JWT Client Authentication", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "JWT Client Authentication - local JWT key and Bearer token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"JWT Auth with hardwired key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\"\n }\n },\n {\n \"name\": \"JWT Auth with external key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication GitOps\",\n \"key\": \"http://192.168.2.5:20080/jwks.json\",\n \"cachetime\": 5\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in auth_token query string parameter\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$arg_auth_token\"\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$http_x_auth_token\"\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "JWT secret fetched from URL", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with external key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete declaration", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "name": "JWT token in auth_token query string parameter", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "HTTP Headers Manipulation", - "item": [ - { - "name": "Create test echo service", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in auth_token query string parameter\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "JWT token in HTTP X-Auth-Token header", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Manipulate headers - server level", - "event": [ + "name": "JWT Client Authentication and Authorization", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "JWT Client Authentication and Authorization", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"JWT AuthN and AuthZ test server\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/auth-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/auth-test.nginx.lab_error_log\"\n },\n \"headers\": {\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-JWT-Group\",\n \"value\": \"$jwt_claim_roles\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"jwt_authentication_local\"\n }\n ]\n },\n \"authorization\": {\n \"profile\": \"jwt role based authorization\"\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"jwt_authentication_local\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Client Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"jwt_type\": \"signed\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"jwt role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Manipulate headers - location level", - "event": [ + "name": "mTLS Client Authentication", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "HTTPS server with mTLS, OCSP, SSL Stapling", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"192.168.1.13\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] - } - ], - "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" - }, - { - "name": "HTTPS server", - "item": [ + ] + }, { - "name": "TLS Offload", - "event": [ + "name": "NGINX App Protect WAF", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Create initial NGINX configuration with NGINX App Protect WAF", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "TLS Offload and NGINX App Protect", - "event": [ + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Change active NGINX App Protect policy", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-allowed\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"Production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"Production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "JWT Client Authentication", - "item": [ - { - "name": "JWT Client Authentication - local JWT key and Bearer token", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"JWT Auth with hardwired key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\"\n }\n },\n {\n \"name\": \"JWT Auth with external key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication GitOps\",\n \"key\": \"http://192.168.2.5:20080/jwks.json\",\n \"cachetime\": 5\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in auth_token query string parameter\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$arg_auth_token\"\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$http_x_auth_token\"\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Update TLS certificates", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "JWT secret fetched from URL", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with external key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.key\"\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "JWT token in auth_token query string parameter", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in auth_token query string parameter\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Disable NGINX App Protect WAF", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "JWT token in HTTP X-Auth-Token header", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "JWT Client Authentication and Authorization", - "item": [ + ] + }, { - "name": "JWT Client Authentication and Authorization", - "event": [ + "name": "NGINX Javascript", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"JWT AuthN and AuthZ test server\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/auth-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/auth-test.nginx.lab_error_log\"\n },\n \"headers\": {\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-JWT-Group\",\n \"value\": \"$jwt_claim_roles\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"jwt_authentication_local\"\n }\n ]\n },\n \"authorization\": {\n \"profile\": \"jwt role based authorization\"\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"jwt_authentication_local\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Client Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"jwt_type\": \"signed\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"jwt role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "NGINX Javascript test", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript" + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "mTLS Client Authentication", - "item": [ + ] + }, { - "name": "HTTPS server with mTLS, OCSP, SSL Stapling", - "event": [ + "name": "Server-side and source of truth authentication", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"192.168.1.13\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Bearer Token, Basic and HTTP header upstream authentication", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "NGINX App Protect WAF", - "item": [ - { - "name": "Create initial NGINX configuration with NGINX App Protect WAF", - "event": [ + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"Bearer token-based authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"Bearer token-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Header-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n },\n {\n \"name\": \"Basic authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"type\": \"basic\",\n \"username\": \"authusername\",\n \"password\": \"YXV0aHBhc3N3b3Jk\"\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "mTLS upstream authentication", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"client_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZBakNDQStxZ0F3SUJBZ0lVYXZ1aFhBOWFLVFJlYmZ2Y1BFU2Z0MjBUQXhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1ZqRUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlZCQWdNQkVOdmNtc3hEVEFMQmdOVkJBY01CRU52Y21zeApFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUll3RkFZRFZRUUREQTEwWlhOMExtRmpiV1F1YkdGdU1CNFhEVEkwCk1EUXhOVEUzTURnMU0xb1hEVEkxTURReE5URTNNRGcxTTFvd1dERUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlYKQkFnTUJFTnZjbXN4RFRBTEJnTlZCQWNNQkVOdmNtc3hFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUmd3RmdZRApWUVFEREE5amJHbGxiblF1WVdOdFpTNXNZV0l3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLCkFvSUNBUURUQ2kydi8rc08rdTJTcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkQKUWkvL0dIZXhYS3NaelBURDUyN0ZMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOApPa3lxVFdma0xkRnF2akFGclU5czMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2CmpsV1E5NTVWUzlmZlNLU3hpQTRCQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUMKRjYrRGZmQ2FNLzVockljRkswSVFheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNOAo5UlhxQmlaNnFWdGFPQXFEK0pRVGNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4CnZvczA4TSsvOUlhWTdQeGtQNXB6bDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0QKbTlURDJKT0hTU3VmdkRkRnV1YjFwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwegpkZ1RsMDVVWjZtMFpFNUdlK1FRaG5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BCmFLZ0hTbTJROE9MS1lJdlhVN1RpME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzQKc3I0UXJ4Q2xuY2pwbUMrdkRmdHJuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJvNEhGTUlIQwpNQWtHQTFVZEV3UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ1dnTURNR0NXQ0dTQUdHK0VJQkRRUW1GaVJQCmNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRGJHbGxiblFnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZGQmIKdmltZDYxekxLdlA0U2RZRFRWbndYdFVwTUI4R0ExVWRJd1FZTUJhQUZLY29GRHpMVnc1QXBiMzB5UTM0c25MZQpHQ1FWTUE0R0ExVWREd0VCL3dRRUF3SUY0REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVICkF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSmg0cm9kZEVGemJwWk5kSW5zUmdubWVnWVIxSWlzUUxRU0IKcmNydEZxVmtLb3Rsc09EUXBFMThIRjBsbVA4WE9IU0hqYytYUVF5YlFNd1ViZ2RNbnhBZE1WaGFaMXppWElnaQpiUHgwOEY0YXR5MElJY1hyOVpFVnZTd1pheURBZHErb2s5RGpoRjQwYU5iQmFBTXB2NTRCL2U3OUNMSWZ6REo4CnNZaWw3K09abWlOUTJtZUNreVBYdXdhd3hTeVRnNVhWS3Q4VEtKQVJ5aTFJeWRHWkZRMTJGWFJHTE1BSjdaYngKRzlPd1ZvazExenpWNkRQZHFuZU5ER3BQRU5WZ2VmVjI0ZU1JVXUrYzhnSThYTU1GMU9VVWR3MmlEQmU4Q01TQQppc2h2aDFWYVZPNC96czlma2dLV2FXejNwQWprN3pkbWdaUnpXRUVHR0JMekJoQk5FQTg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"client_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRFRDaTJ2LytzTyt1MlMKcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkRRaS8vR0hleFhLc1p6UFRENTI3RgpMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOE9reXFUV2ZrTGRGcXZqQUZyVTlzCjMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2amxXUTk1NVZTOWZmU0tTeGlBNEIKQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUNGNitEZmZDYU0vNWhySWNGSzBJUQpheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNODlSWHFCaVo2cVZ0YU9BcUQrSlFUCmNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4dm9zMDhNKy85SWFZN1B4a1A1cHoKbDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0RtOVREMkpPSFNTdWZ2RGRGdXViMQpwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwemRnVGwwNVVaNm0wWkU1R2UrUVFoCm5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BYUtnSFNtMlE4T0xLWUl2WFU3VGkKME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzRzcjRRcnhDbG5janBtQyt2RGZ0cgpuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJBb0lDQUJzWEZBK2krRmVFbW5rdE9xdHRUL1FsCk5TUlozL05WYjJuRlcyUGRqRHhKcGtUTzV2VS9qYThVd2ZmTVIrdWxCbWhSWkVmOFBweVBMc2J5USszV29iSjAKUk9JQlprVjdYd2ZDWDdEVUJDc0VtS3ZscDlvN3JVQmJqV0w1SmpJNDhYeDI3VFR0NlFMY05uVXhUZDUxanRPagpXYXFJdzNqNU1Oc0tFdDRncWlET2RhQzIvMzJaekZkTHNHNWdnRmRnUElZOUpYUXN3bHk2VnZjdzVpU0RoTnRICkcyYWxYYXdiL2s1Sk9OWTIyY3RDT0kyUnhPUGtPc3lYRkoxYTBRQStGYmxBWExKenVubE5ZNU9iOXEwWTFpa2sKSHpGeXBUcENSdmY2dzY3em00NUYvZVdkS0MzdmpnM29JK29GUS9vMTJUdjhWV3Bhc0ptSmoraUJ5aFRpOGx4YQpMempXaHNrUFZJUGJDYjFDTmIzZHNQSWVWYTVQYmRORGh2bHBQZFV4cXhKRGI4ZUFhemxSQXJVdmtaQnpkTjZtCjVwekljNGtMQnd3Wno5eGg1MzdsQ0tlZ3ZJYmdEMlQvMEM4SVFsWmFIK1M3azlWaVU2Z1RWSGNzU1RsSm52NVYKN3VCMWczVzJZRVloZFJxNlJOUXRZaUFuTktUS2ZYb3d1UUJteWRwVWRYWUljTE5GcER6eHgvRGdQSEhnU0J1dQpQZXVMZzdpemhSSndKMTQ1eW5VTlloQnROVVJaOWlRL1cwWTJOa242UWFBZDNld1pLaVg0S3lZU2k3TTF1MFJWCmFDc1BmZWJrWkRTUnRnQ2Q5N3dGSVYyTVh0UnpXNlpKUUlDWkhHTDVkYkJrNU0xQTI2NnJSYmcvTWZJSE9mdTMKRUZBVjc2aXoyVmNtSDRzblNZUHhBb0lCQVFEc0pNWElhM3ZyRXdRSkh0alRWZE9ONk9rbEExRVN4aWtjSWdSOAo3aFRWQXk3dmtORlpFVUhYczQ1TXlYQzRxTWlvUnFhZHVtOXpQWnFBQ0tQMHRWcXdDMVdOcUFrbDBQc1pZYXcrCmpKNjRDQXA4ZnJ4UDUrOVpWREtiamRWK1ZrK1lrbC9UL0Q1djNFTnZIdkVxN3ZMSE56dE9VSmFWZXNFRERQSW8KaER5SHhjRXQwTHRXTFhoNGNMSDhIQk9Kc0wxYXcxRlhNTk1qdERzazlBMTlJRFlYTHcwaWpIeC81c3hHUGcxSQpmMXRIemhpTlN5NUU5RG9pTmJxVFQvWEEyYVdCdjJ1ZlQybmw2ekticHZHNVo0VGlOUE5ESU5MaUFXOVNNQnJnCkJtaXJFVHU4MnVSa3hnaWZTM01CZ0ZFdXVtaSt2cEhwNzhGaUNOcHpZZUFwTUxjN0FvSUJBUURreVFVT29HVjEKTzZaNXJ4KzhLbVh1S3dmbXNHNmh5cmkrNEw4MzRQakVhbHdkdFhFUmphUG8vSTVhOVFoYjNnLzF5SUdiMzdLSgpPaTFCcGVRZ1owUEVQdFgyRWI0QTNCSTA5SzExWWFybnJGM2d6WS9CVWgveEZoL1YvVEVzTTloZTZ4YlhtRm9WCktvMlY1b2NlNnQzNUJuNHVLL2xkSEJKMHJnUENQdXNKVU9JMEhtUzZkdXNQcHczRFpESkZ5SEU4anptSllwcUsKMnBEMlBBMVZ5aVBBM3MwOU12TWdNSmJXajJLQVBoYk4xQXJnTERaUTFuZ0VwaVFtM3hWdmxIVkMzN0JHM0IzcApWbmtSRE9UZnF1N1BXek40aHZnMDRaNkxBdEZuYzNnMFFxRGcvcXZlS0xuclZwOUJEUlhWb0pZZkNMaVBkajZCCmFiYnFXQ0lYTnMwTkFvSUJBUURFWllrQk9UT2t2UG44UStWOVRzSldJa0hWZ0w2cTZKaEVSNTZIOE5MdW5ta28KNGI3Ylh0anQ5dTRBdXdDKzg5Ris4dE9jRnZTZVdidm5oRWdvTzdTaSthbzcyR2RUUmsyd1BHV3UxL0VoaWI1Kwo4RURhREVJcWZ6WmYzVVNVZ0dCT3VsNXN4anQvZVNlMGdYMStnYUQxUXVCV0wvd3RjaHlZMXVtSC9RTUN3TnY3CnFNQkYyaWQ1cy9Demh2NVE0K2Q0VnoyTlVKUXArN204OENWUHpieHU1N2o2NVBDZXgydFplRDQvNzN3UmFqMU4KTmh2VFNYUVlBNnVhM1VPOUVzYnQ5REFrSFQ0cjlNTHdaWlpnNXRIRCtObmhHS21MUWpvOWxyaWpYWEVyNVhkVAppSkd2cG15Qlg1VFV5TTI4R1ZrSVd5S3I5N1ZVUFp6Qm5jTjdQb01GQW9JQkFDSWRCekFESXAyMFkwSkpwb1c4CkhLN0NvODcyQjhrQUhVUDQ1d3BCOVZYME5nQUlDZkFBR3F5bTIrTWNIajcwZ1pTNGJQcjlBL1lLUXExRE94ekoKeVFUK0NaRkRXLzFzMHhvcVVhTHJDVHk2S3RWV1VWVVdGY1V3ODFaSkJvZjh3d3FFSzBmQ1k4dzhLQmh0NHovcwo3V1F3WDZncXptZmZ3N0M2TWIxSS9HckxNSzlzeU1BMDh4L0dYUHNCZWEyR0VieGg3c1paZVlteXhXS3gyWnN0CkpOK2hXU0VDODlXYzZTRGRDR2J1MngrZHVuRnFwajZ2ZS8zVmVCYUR0UUtLTkdIZ1VMeUFIY1dwS3l3cnJBVGQKeS9ZSE4wbUZkb1VNRDBQVEM3NU5MV005ZkJlUVliZ2lnblpnMkNZdStVNTlQMlVwTzd2SWVkRjZIZGdiaEJuSwpCaEVDZ2dFQkFNZmQ2Zi90RThTQlNFUnd5YW80SThuZkhTZUlMUklvM3pqRE5vWHZ6VHlwbG00a3ovYW9QeEF0CmhPYVNmZU41bFljMXFFUkRxZzRIVGRNTUkyenZPaVFuMHNGTEJFZ0UwT0VIOEZxZVZlZGgycUJucFdXWEhwTW8KREd4TnhpUnVpSDZpOEVMVWFoaU1NQkdQVi9ONjI5MDREbnUyYVVHcHlMTzZxems3SmM5VXlITC90QVNRTFIzagp6NFBhb2xTRE5rNzJSUks0VjIyZUprM2EwYVhjRU5vM1R0OUlTUTliMG5DYVVKbFJsZTA0d2QrOWUyN0FRNUNaCkVWbUtZT1JYcW9VTGNQOEcxRm1VUGhDRkU2aEI3L1hSVWpQdmJFdm5rS05Cdko2UHppT0RMdktRK3I4TzR0WkMKQi9LTDlCdjNmdUkvQlJLeU9WZVU1VnZ5MzUveUFxVT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"mTLS authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"mTLS authentication profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"certificate\": \"client_cert\",\n \"key\": \"client_key\"\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + }, + "response": [] } - }, - "response": [] - }, + ] + } + ] + }, + { + "name": "NGINX One", + "item": [ { - "name": "Change active NGINX App Protect policy", - "event": [ + "name": "API Gateway", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-allowed\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"Production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"Production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Ergast API", + "item": [ + { + "name": "Ergast API Gateway and DevPortal with redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Ergast API Gateway and DevPortal with backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" ] - } - }, - "response": [] - }, - { - "name": "Update TLS certificates", - "event": [ + }, { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.key\"\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Petstore API", + "item": [ + { + "name": "Petstore API Gateway RateLimit", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:80\",\n \"http2\": true\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:80\",\n \"http2\": true\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" ] - } - }, - "response": [] - }, - { - "name": "Disable NGINX App Protect WAF", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "NGINX Javascript", - "item": [ - { - "name": "NGINX Javascript test", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Petstore & Ergast API Gateway all in one", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore and Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"192.168.2.13\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n },\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"rate_limit\": [\n {\n \"profile\": \"ergast_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"ergast_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n },\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "Server-side and source of truth authentication", - "item": [ + ] + }, { - "name": "Bearer Token, Basic and HTTP header upstream authentication", - "event": [ + "name": "CRUD automation", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"Bearer token-based authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"Bearer token-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Header-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n },\n {\n \"name\": \"Basic authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"type\": \"basic\",\n \"username\": \"authusername\",\n \"password\": \"YXV0aHBhc3N3b3Jk\"\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Create initial NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "mTLS upstream authentication", - "event": [ + "name": "Housekeeping - common endpoints", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"client_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZBakNDQStxZ0F3SUJBZ0lVYXZ1aFhBOWFLVFJlYmZ2Y1BFU2Z0MjBUQXhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1ZqRUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlZCQWdNQkVOdmNtc3hEVEFMQmdOVkJBY01CRU52Y21zeApFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUll3RkFZRFZRUUREQTEwWlhOMExtRmpiV1F1YkdGdU1CNFhEVEkwCk1EUXhOVEUzTURnMU0xb1hEVEkxTURReE5URTNNRGcxTTFvd1dERUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlYKQkFnTUJFTnZjbXN4RFRBTEJnTlZCQWNNQkVOdmNtc3hFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUmd3RmdZRApWUVFEREE5amJHbGxiblF1WVdOdFpTNXNZV0l3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLCkFvSUNBUURUQ2kydi8rc08rdTJTcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkQKUWkvL0dIZXhYS3NaelBURDUyN0ZMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOApPa3lxVFdma0xkRnF2akFGclU5czMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2CmpsV1E5NTVWUzlmZlNLU3hpQTRCQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUMKRjYrRGZmQ2FNLzVockljRkswSVFheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNOAo5UlhxQmlaNnFWdGFPQXFEK0pRVGNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4CnZvczA4TSsvOUlhWTdQeGtQNXB6bDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0QKbTlURDJKT0hTU3VmdkRkRnV1YjFwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwegpkZ1RsMDVVWjZtMFpFNUdlK1FRaG5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BCmFLZ0hTbTJROE9MS1lJdlhVN1RpME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzQKc3I0UXJ4Q2xuY2pwbUMrdkRmdHJuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJvNEhGTUlIQwpNQWtHQTFVZEV3UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ1dnTURNR0NXQ0dTQUdHK0VJQkRRUW1GaVJQCmNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRGJHbGxiblFnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZGQmIKdmltZDYxekxLdlA0U2RZRFRWbndYdFVwTUI4R0ExVWRJd1FZTUJhQUZLY29GRHpMVnc1QXBiMzB5UTM0c25MZQpHQ1FWTUE0R0ExVWREd0VCL3dRRUF3SUY0REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVICkF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSmg0cm9kZEVGemJwWk5kSW5zUmdubWVnWVIxSWlzUUxRU0IKcmNydEZxVmtLb3Rsc09EUXBFMThIRjBsbVA4WE9IU0hqYytYUVF5YlFNd1ViZ2RNbnhBZE1WaGFaMXppWElnaQpiUHgwOEY0YXR5MElJY1hyOVpFVnZTd1pheURBZHErb2s5RGpoRjQwYU5iQmFBTXB2NTRCL2U3OUNMSWZ6REo4CnNZaWw3K09abWlOUTJtZUNreVBYdXdhd3hTeVRnNVhWS3Q4VEtKQVJ5aTFJeWRHWkZRMTJGWFJHTE1BSjdaYngKRzlPd1ZvazExenpWNkRQZHFuZU5ER3BQRU5WZ2VmVjI0ZU1JVXUrYzhnSThYTU1GMU9VVWR3MmlEQmU4Q01TQQppc2h2aDFWYVZPNC96czlma2dLV2FXejNwQWprN3pkbWdaUnpXRUVHR0JMekJoQk5FQTg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"client_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRFRDaTJ2LytzTyt1MlMKcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkRRaS8vR0hleFhLc1p6UFRENTI3RgpMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOE9reXFUV2ZrTGRGcXZqQUZyVTlzCjMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2amxXUTk1NVZTOWZmU0tTeGlBNEIKQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUNGNitEZmZDYU0vNWhySWNGSzBJUQpheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNODlSWHFCaVo2cVZ0YU9BcUQrSlFUCmNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4dm9zMDhNKy85SWFZN1B4a1A1cHoKbDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0RtOVREMkpPSFNTdWZ2RGRGdXViMQpwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwemRnVGwwNVVaNm0wWkU1R2UrUVFoCm5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BYUtnSFNtMlE4T0xLWUl2WFU3VGkKME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzRzcjRRcnhDbG5janBtQyt2RGZ0cgpuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJBb0lDQUJzWEZBK2krRmVFbW5rdE9xdHRUL1FsCk5TUlozL05WYjJuRlcyUGRqRHhKcGtUTzV2VS9qYThVd2ZmTVIrdWxCbWhSWkVmOFBweVBMc2J5USszV29iSjAKUk9JQlprVjdYd2ZDWDdEVUJDc0VtS3ZscDlvN3JVQmJqV0w1SmpJNDhYeDI3VFR0NlFMY05uVXhUZDUxanRPagpXYXFJdzNqNU1Oc0tFdDRncWlET2RhQzIvMzJaekZkTHNHNWdnRmRnUElZOUpYUXN3bHk2VnZjdzVpU0RoTnRICkcyYWxYYXdiL2s1Sk9OWTIyY3RDT0kyUnhPUGtPc3lYRkoxYTBRQStGYmxBWExKenVubE5ZNU9iOXEwWTFpa2sKSHpGeXBUcENSdmY2dzY3em00NUYvZVdkS0MzdmpnM29JK29GUS9vMTJUdjhWV3Bhc0ptSmoraUJ5aFRpOGx4YQpMempXaHNrUFZJUGJDYjFDTmIzZHNQSWVWYTVQYmRORGh2bHBQZFV4cXhKRGI4ZUFhemxSQXJVdmtaQnpkTjZtCjVwekljNGtMQnd3Wno5eGg1MzdsQ0tlZ3ZJYmdEMlQvMEM4SVFsWmFIK1M3azlWaVU2Z1RWSGNzU1RsSm52NVYKN3VCMWczVzJZRVloZFJxNlJOUXRZaUFuTktUS2ZYb3d1UUJteWRwVWRYWUljTE5GcER6eHgvRGdQSEhnU0J1dQpQZXVMZzdpemhSSndKMTQ1eW5VTlloQnROVVJaOWlRL1cwWTJOa242UWFBZDNld1pLaVg0S3lZU2k3TTF1MFJWCmFDc1BmZWJrWkRTUnRnQ2Q5N3dGSVYyTVh0UnpXNlpKUUlDWkhHTDVkYkJrNU0xQTI2NnJSYmcvTWZJSE9mdTMKRUZBVjc2aXoyVmNtSDRzblNZUHhBb0lCQVFEc0pNWElhM3ZyRXdRSkh0alRWZE9ONk9rbEExRVN4aWtjSWdSOAo3aFRWQXk3dmtORlpFVUhYczQ1TXlYQzRxTWlvUnFhZHVtOXpQWnFBQ0tQMHRWcXdDMVdOcUFrbDBQc1pZYXcrCmpKNjRDQXA4ZnJ4UDUrOVpWREtiamRWK1ZrK1lrbC9UL0Q1djNFTnZIdkVxN3ZMSE56dE9VSmFWZXNFRERQSW8KaER5SHhjRXQwTHRXTFhoNGNMSDhIQk9Kc0wxYXcxRlhNTk1qdERzazlBMTlJRFlYTHcwaWpIeC81c3hHUGcxSQpmMXRIemhpTlN5NUU5RG9pTmJxVFQvWEEyYVdCdjJ1ZlQybmw2ekticHZHNVo0VGlOUE5ESU5MaUFXOVNNQnJnCkJtaXJFVHU4MnVSa3hnaWZTM01CZ0ZFdXVtaSt2cEhwNzhGaUNOcHpZZUFwTUxjN0FvSUJBUURreVFVT29HVjEKTzZaNXJ4KzhLbVh1S3dmbXNHNmh5cmkrNEw4MzRQakVhbHdkdFhFUmphUG8vSTVhOVFoYjNnLzF5SUdiMzdLSgpPaTFCcGVRZ1owUEVQdFgyRWI0QTNCSTA5SzExWWFybnJGM2d6WS9CVWgveEZoL1YvVEVzTTloZTZ4YlhtRm9WCktvMlY1b2NlNnQzNUJuNHVLL2xkSEJKMHJnUENQdXNKVU9JMEhtUzZkdXNQcHczRFpESkZ5SEU4anptSllwcUsKMnBEMlBBMVZ5aVBBM3MwOU12TWdNSmJXajJLQVBoYk4xQXJnTERaUTFuZ0VwaVFtM3hWdmxIVkMzN0JHM0IzcApWbmtSRE9UZnF1N1BXek40aHZnMDRaNkxBdEZuYzNnMFFxRGcvcXZlS0xuclZwOUJEUlhWb0pZZkNMaVBkajZCCmFiYnFXQ0lYTnMwTkFvSUJBUURFWllrQk9UT2t2UG44UStWOVRzSldJa0hWZ0w2cTZKaEVSNTZIOE5MdW5ta28KNGI3Ylh0anQ5dTRBdXdDKzg5Ris4dE9jRnZTZVdidm5oRWdvTzdTaSthbzcyR2RUUmsyd1BHV3UxL0VoaWI1Kwo4RURhREVJcWZ6WmYzVVNVZ0dCT3VsNXN4anQvZVNlMGdYMStnYUQxUXVCV0wvd3RjaHlZMXVtSC9RTUN3TnY3CnFNQkYyaWQ1cy9Demh2NVE0K2Q0VnoyTlVKUXArN204OENWUHpieHU1N2o2NVBDZXgydFplRDQvNzN3UmFqMU4KTmh2VFNYUVlBNnVhM1VPOUVzYnQ5REFrSFQ0cjlNTHdaWlpnNXRIRCtObmhHS21MUWpvOWxyaWpYWEVyNVhkVAppSkd2cG15Qlg1VFV5TTI4R1ZrSVd5S3I5N1ZVUFp6Qm5jTjdQb01GQW9JQkFDSWRCekFESXAyMFkwSkpwb1c4CkhLN0NvODcyQjhrQUhVUDQ1d3BCOVZYME5nQUlDZkFBR3F5bTIrTWNIajcwZ1pTNGJQcjlBL1lLUXExRE94ekoKeVFUK0NaRkRXLzFzMHhvcVVhTHJDVHk2S3RWV1VWVVdGY1V3ODFaSkJvZjh3d3FFSzBmQ1k4dzhLQmh0NHovcwo3V1F3WDZncXptZmZ3N0M2TWIxSS9HckxNSzlzeU1BMDh4L0dYUHNCZWEyR0VieGg3c1paZVlteXhXS3gyWnN0CkpOK2hXU0VDODlXYzZTRGRDR2J1MngrZHVuRnFwajZ2ZS8zVmVCYUR0UUtLTkdIZ1VMeUFIY1dwS3l3cnJBVGQKeS9ZSE4wbUZkb1VNRDBQVEM3NU5MV005ZkJlUVliZ2lnblpnMkNZdStVNTlQMlVwTzd2SWVkRjZIZGdiaEJuSwpCaEVDZ2dFQkFNZmQ2Zi90RThTQlNFUnd5YW80SThuZkhTZUlMUklvM3pqRE5vWHZ6VHlwbG00a3ovYW9QeEF0CmhPYVNmZU41bFljMXFFUkRxZzRIVGRNTUkyenZPaVFuMHNGTEJFZ0UwT0VIOEZxZVZlZGgycUJucFdXWEhwTW8KREd4TnhpUnVpSDZpOEVMVWFoaU1NQkdQVi9ONjI5MDREbnUyYVVHcHlMTzZxems3SmM5VXlITC90QVNRTFIzagp6NFBhb2xTRE5rNzJSUks0VjIyZUprM2EwYVhjRU5vM1R0OUlTUTliMG5DYVVKbFJsZTA0d2QrOWUyN0FRNUNaCkVWbUtZT1JYcW9VTGNQOEcxRm1VUGhDRkU2aEI3L1hSVWpQdmJFdm5rS05Cdko2UHppT0RMdktRK3I4TzR0WkMKQi9LTDlCdjNmdUkvQlJLeU9WZVU1VnZ5MzUveUFxVT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"mTLS authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"mTLS authentication profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"certificate\": \"client_cert\",\n \"key\": \"client_key\"\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Clean NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - } - ] - } - ], - "description": "[https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v4.2.md](https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v4.2.md)" - }, - { - "name": "v5.0", - "item": [ - { - "name": "Configuration generation", - "item": [ - { - "name": "Basic - LB", - "item": [ - { - "name": "Basic - LB - plaintext output", - "event": [ + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"plaintext\"\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample L4 service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"l4_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"A sample HTTP service\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Basic - LB - json b64 encoded output", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"json\"\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample L4 service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"l4_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"A sample HTTP service\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Get declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } } - } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" + { + "name": "Delete declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Basic - LB - ConfigMap output", - "event": [ + "name": "HTTP Headers Manipulation", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"configmap\",\n \"configmap\": {\n \"name\": \"nginx.test\",\n \"filename\": \"testservice.conf\",\n \"namespace\": \"test-namespace\"\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample L4 service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"l4_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"A sample HTTP service\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Create test echo service", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Basic - LB - HTTP output", - "event": [ + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"http\",\n \"http\": {\n \"url\": \"http://192.168.2.19:8080/path/service\"\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample L4 service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"l4_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"A sample HTTP service\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Manipulate headers - server level", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Advanced", - "item": [ - { - "name": "Advanced LB - plaintext output", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"plaintext\"\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample_layer4_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\",\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"upstream\": \"l4_upstream\",\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbDQgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/test\",\n \"urimatch\": \"exact\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true,\n \"uri\": \"/healthcheck\",\n \"interval\": 5,\n \"fails\": 3,\n \"passes\": 2\n },\n \"rate_limit\": {\n \"profile\": \"test_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 10,\n \"delay\": 3\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_illegal\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbG9jYXRpb24gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_blocked\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgc2VydmVyIHNuaXBwZXQgY29tbWVudAo=\"\n }\n },\n {\n \"name\": \"another HTTP test application\",\n \"names\": [\n \"server_443\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"10.0.0.2:80\",\n \"backup\": true\n }\n ],\n \"sticky\": {\n \"cookie\": \"cookie_name\",\n \"expires\": \"1h\",\n \"domain\": \".testserver\",\n \"path\": \"/\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"test_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n }\n ],\n \"maps\": [\n {\n \"match\": \"$host$request_uri\",\n \"variable\": \"$backend\",\n \"entries\": [\n {\n \"key\": \"www.test.lab/app1/\",\n \"keymatch\": \"iregex\",\n \"value\": \"upstream_1\"\n },\n {\n \"key\": \"(.*).test.lab/app2/\",\n \"keymatch\": \"regex\",\n \"value\": \"upstream_2\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": true,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgSFRUUCBzbmlwcGV0IGNvbW1lbnQK\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Manipulate headers - location level", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.details.message.configUid] = respData.details.message.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.details.message.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] } - }, - "response": [] + ], + "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" }, { - "name": "Advanced LB - json b64 encoded output", - "event": [ + "name": "HTTPS server", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"json\"\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample_layer4_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\",\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"upstream\": \"l4_upstream\",\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbDQgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/test\",\n \"urimatch\": \"exact\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true,\n \"uri\": \"/healthcheck\",\n \"interval\": 5,\n \"fails\": 3,\n \"passes\": 2\n },\n \"rate_limit\": {\n \"profile\": \"test_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 10,\n \"delay\": 3\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_illegal\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbG9jYXRpb24gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_blocked\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgc2VydmVyIHNuaXBwZXQgY29tbWVudAo=\"\n }\n },\n {\n \"name\": \"another HTTP test application\",\n \"names\": [\n \"server_443\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"10.0.0.2:80\",\n \"backup\": true\n }\n ],\n \"sticky\": {\n \"cookie\": \"cookie_name\",\n \"expires\": \"1h\",\n \"domain\": \".testserver\",\n \"path\": \"/\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"test_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n }\n ],\n \"maps\": [\n {\n \"match\": \"$host$request_uri\",\n \"variable\": \"$backend\",\n \"entries\": [\n {\n \"key\": \"www.test.lab/app1/\",\n \"keymatch\": \"iregex\",\n \"value\": \"upstream_1\"\n },\n {\n \"key\": \"(.*).test.lab/app2/\",\n \"keymatch\": \"regex\",\n \"value\": \"upstream_2\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": true,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgSFRUUCBzbmlwcGV0IGNvbW1lbnQK\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "TLS Offload", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Advanced LB - ConfigMap output", - "event": [ + "name": "mTLS Client Authentication", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"configmap\",\n \"configmap\": {\n \"name\": \"nginx.test\",\n \"filename\": \"testservice.conf\",\n \"namespace\": \"test-namespace\"\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample_layer4_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\",\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"upstream\": \"l4_upstream\",\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbDQgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/test\",\n \"urimatch\": \"exact\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true,\n \"uri\": \"/healthcheck\",\n \"interval\": 5,\n \"fails\": 3,\n \"passes\": 2\n },\n \"rate_limit\": {\n \"profile\": \"test_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 10,\n \"delay\": 3\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_illegal\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbG9jYXRpb24gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_blocked\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgc2VydmVyIHNuaXBwZXQgY29tbWVudAo=\"\n }\n },\n {\n \"name\": \"another HTTP test application\",\n \"names\": [\n \"server_443\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"10.0.0.2:80\",\n \"backup\": true\n }\n ],\n \"sticky\": {\n \"cookie\": \"cookie_name\",\n \"expires\": \"1h\",\n \"domain\": \".testserver\",\n \"path\": \"/\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"test_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n }\n ],\n \"maps\": [\n {\n \"match\": \"$host$request_uri\",\n \"variable\": \"$backend\",\n \"entries\": [\n {\n \"key\": \"www.test.lab/app1/\",\n \"keymatch\": \"iregex\",\n \"value\": \"upstream_1\"\n },\n {\n \"key\": \"(.*).test.lab/app2/\",\n \"keymatch\": \"regex\",\n \"value\": \"upstream_2\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": true,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgSFRUUCBzbmlwcGV0IGNvbW1lbnQK\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "HTTPS server with mTLS, OCSP, SSL Stapling", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"192.168.1.13\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + }, + "response": [] } - }, - "response": [] + ] }, { - "name": "Advanced LB - HTTP output", - "event": [ + "name": "NGINX Javascript", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"http\",\n \"http\": {\n \"url\": \"http://192.168.1.19:8080/path/service\"\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"sample_layer4_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\",\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"upstream\": \"l4_upstream\",\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbDQgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"l4_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n }\n ]\n }\n ]\n },\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"server_8080.nginx.lab\",\n \"server_8081.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/test\",\n \"urimatch\": \"exact\",\n \"upstream\": \"http://test_upstream\",\n \"health_check\": {\n \"enabled\": true,\n \"uri\": \"/healthcheck\",\n \"interval\": 5,\n \"fails\": 3,\n \"passes\": 2\n },\n \"rate_limit\": {\n \"profile\": \"test_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 10,\n \"delay\": 3\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_illegal\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgbG9jYXRpb24gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"test_policy\",\n \"log\": {\n \"profile_name\": \"log_blocked\",\n \"enabled\": true,\n \"destination\": \"192.168.1.5:514\"\n }\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgc2VydmVyIHNuaXBwZXQgY29tbWVudAo=\"\n }\n },\n {\n \"name\": \"another HTTP test application\",\n \"names\": [\n \"server_443\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"10.0.0.2:80\",\n \"backup\": true\n }\n ],\n \"sticky\": {\n \"cookie\": \"cookie_name\",\n \"expires\": \"1h\",\n \"domain\": \".testserver\",\n \"path\": \"/\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgdXBzdHJlYW0gc25pcHBldCBjb21tZW50Cg==\"\n }\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"test_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n }\n ],\n \"maps\": [\n {\n \"match\": \"$host$request_uri\",\n \"variable\": \"$backend\",\n \"entries\": [\n {\n \"key\": \"www.test.lab/app1/\",\n \"keymatch\": \"iregex\",\n \"value\": \"upstream_1\"\n },\n {\n \"key\": \"(.*).test.lab/app2/\",\n \"keymatch\": \"regex\",\n \"value\": \"upstream_2\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": true,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n },\n \"snippet\": {\n \"content\": \"IyBUaGlzIGlzIGEgSFRUUCBzbmlwcGV0IGNvbW1lbnQK\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "NGINX Javascript test", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] } - }, - "response": [] + ] } ] } ] - }, + } + ], + "description": "[https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v5.0.md](https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v4.2.md)" + }, + { + "name": "v5.1", + "item": [ { - "name": "Declarative automation examples", + "name": "NGINX Instance Manager", "item": [ { - "name": "NGINX Instance Manager", + "name": "API Gateway", "item": [ { - "name": "API Gateway", + "name": "Ergast API", "item": [ { - "name": "Ergast API", - "item": [ + "name": "Ergast API Gateway and DevPortal with redocly", + "event": [ { - "name": "Ergast API Gateway and DevPortal with redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Ergast API Gateway and DevPortal with backstage", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Petstore API", + "item": [ + { + "name": "API Client test requests", + "item": [ + { + "name": "Get Inventory (legitimate request)", "request": { - "method": "POST", + "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "" + } + }, + "response": [] + }, + { + "name": "Get Inventory (malicious query string)", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://apigw.nginx.lab/petstore/store/inventory?/etc/passwd", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "store", + "inventory" + ], + "query": [ + { + "key": "/etc/passwd", + "value": null + } ] } }, "response": [] }, { - "name": "Ergast API Gateway and DevPortal with backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "name": "Get Inventory (XSS attack)", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "" } - ], + }, + "response": [] + }, + { + "name": "Login without token", "request": { - "method": "POST", + "method": "GET", "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\" \n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "url": { + "raw": "" + } + }, + "response": [] + }, + { + "name": "Login with \"DevOps\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU", + "type": "string" } - } + ] }, + "method": "GET", + "header": [], "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "" + } + }, + "response": [] + }, + { + "name": "Login with \"Guest\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQWxpY2UgR3Vlc3QiLCJzdWIiOiJKV1Qgc3ViIGNsYWltIiwiaXNzIjoiSldUIGlzcyBjbGFpbSIsInJvbGVzIjpbImd1ZXN0Il19.jFJDq-33irz7uFxdI8c8fIb5TwTAU5BlemmIFVALUAE", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "https://apigw.nginx.lab/petstore/user/login", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "user", + "login" ] } }, "response": [] - } - ] - }, - { - "name": "Petstore API", - "item": [ + }, { - "name": "Petstore API Gateway RateLimit", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], + "name": "Login with dual (DevOps & Guest) role token", "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIiwiZ3Vlc3QiXX0.3ES7aVquklWqlZ4OWzt8rBz5px4kKZRgvifFVNomCsU", + "type": "string" } - } + ] }, + "method": "GET", + "header": [], "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "https://apigw.nginx.lab/petstore/user/login", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "user", + "login" ] } }, "response": [] }, { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], + "name": "Upload pet image without token", "request": { "method": "POST", "header": [], "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" } - } + ] }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "pet", + "1", + "uploadImage" ] } }, "response": [] }, { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], + "name": "Upload pet image with \"DevOps\" token", "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU", + "type": "string" + } + ] + }, "method": "POST", "header": [], "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" } - } + ] }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "pet", + "1", + "uploadImage" ] } }, "response": [] }, { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], + "name": "Upload pet image with \"Guest\" token", "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQWxpY2UgR3Vlc3QiLCJzdWIiOiJKV1Qgc3ViIGNsYWltIiwiaXNzIjoiSldUIGlzcyBjbGFpbSIsInJvbGVzIjpbImd1ZXN0Il19.jFJDq-33irz7uFxdI8c8fIb5TwTAU5BlemmIFVALUAE", + "type": "string" + } + ] + }, "method": "POST", "header": [], "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" } - } + ] }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", "host": [ - "{{ncg_host}}" + "apigw", + "nginx", + "lab" ], - "port": "{{ncg_port}}", "path": [ - "{{ngc_api_version}}", - "config" + "petstore", + "pet", + "1", + "uploadImage" ] } }, "response": [] + } + ], + "description": "This folder contains requests to access the Petstore API published through NGINX using the Declarative API" + }, + { + "name": "Petstore API Gateway RateLimit", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + redocly", + "event": [ { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly + moesif", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ndk_http_module\",\n \"ngx_http_lua_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"visibility\": [\n {\n \"enabled\": true,\n \"type\": \"moesif\",\n \"moesif\": {\n \"application_id\": \"{{moesif_application_id}}\"\n }\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", + "event": [ { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] + }, + "response": [] }, { - "name": "Petstore & Ergast API Gateway all in one", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + WAF + backstage", "event": [ { "listen": "test", @@ -3009,7 +3994,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore and Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"192.168.2.13\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/petstore-devportal.html\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n },\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"uri\": \"/ergast-devportal.html\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"ergast_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"ergast_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n },\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n }\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-blocked-bot-allowed.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n },\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -3031,1159 +4016,1709 @@ }, "response": [] } - ] + ] + } + ] + }, + { + "name": "CRUD automation", + "item": [ + { + "name": "Create initial NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Update HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] }, { - "name": "CRUD automation", - "item": [ + "name": "Modify and add HTTP upstream", + "event": [ { - "name": "Create initial NGINX configuration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add stream server and upstream", + "event": [ { - "name": "Update HTTP upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove HTTP server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add Stream server and upstream", + "event": [ { - "name": "Modify and add HTTP upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #2", + "event": [ { - "name": "Modify and add HTTP server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server_v2.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_v2_log\",\n \"error\": \"/var/log/nginx/error_v2_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream_added\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.100:80\",\n \"weight\": 5,\n \"max_fails\": 2,\n \"fail_timeout\": \"30s\",\n \"max_conns\": 3,\n \"slow_start\": \"30s\"\n },\n {\n \"server\": \"192.168.1.101:80\"\n },\n {\n \"server\": \"192.168.1.102:80\"\n },\n {\n \"server\": \"192.168.1.103:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "GitOps autosync", + "item": [ + { + "name": "NGINX Plus and GitOps", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "NGINX App Protect WAF and GitOps", + "event": [ { - "name": "Remove HTTP server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"gitops\",\n \"versions\": [\n {\n \"tag\": \"gitops\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-gitops.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration", + "event": [ { - "name": "Modify Stream server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Delete declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Housekeeping - common endpoints", + "item": [ + { + "name": "Clean NGINX configuration", + "event": [ { - "name": "Add stream server and upstream", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Delete declaration", + "event": [ { - "name": "Remove stream server and upstream #1", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "HTTP Headers Manipulation", + "item": [ + { + "name": "Create test echo service", + "event": [ { - "name": "Remove stream server and upstream #2", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] + }, + "response": [] }, { - "name": "GitOps autosync", - "item": [ + "name": "Manipulate headers - server level", + "event": [ { - "name": "NGINX Plus and GitOps", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.1/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "NGINX App Protect WAF and GitOps", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 5,\n \"modules\": [\n \"ngx_http_app_protect_module\",\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"gitops\",\n \"versions\": [\n {\n \"tag\": \"gitops\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/nap-policy-gitops.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Manipulate headers - location level", + "event": [ { - "name": "Get declaration status", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}", - "status" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ], + "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" + }, + { + "name": "HTTPS server", + "item": [ + { + "name": "TLS Offload", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "TLS Offload and NGINX App Protect", + "event": [ { - "name": "Get declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-blocked.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "JWT Client Authentication", + "item": [ + { + "name": "JWT Client Authentication - local JWT key and Bearer token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"JWT Auth with hardwired key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\"\n }\n },\n {\n \"name\": \"JWT Auth with external key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication GitOps\",\n \"key\": \"http://192.168.2.5:20080/jwks.json\",\n \"cachetime\": 5\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in auth_token query string parameter\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$arg_auth_token\"\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$http_x_auth_token\"\n }\n }\n ]\n },\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "JWT secret fetched from URL", + "event": [ { - "name": "Delete declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with external key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - ] + }, + "response": [] }, { - "name": "Housekeeping - common endpoints", - "item": [ + "name": "JWT token in auth_token query string parameter", + "event": [ { - "name": "Clean NGINX configuration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\"\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in auth_token query string parameter\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "Get declaration status", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}", - "status" - ] - } - }, - "response": [] - }, + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "JWT token in HTTP X-Auth-Token header", + "event": [ { - "name": "Get declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "JWT Client Authentication and Authorization", + "item": [ + { + "name": "JWT Client Authentication and Authorization", + "event": [ { - "name": "Delete declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"JWT AuthN and AuthZ test server\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/auth-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/auth-test.nginx.lab_error_log\"\n },\n \"headers\": {\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-JWT-Group\",\n \"value\": \"$jwt_claim_roles\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"jwt_authentication_local\"\n }\n ]\n },\n \"authorization\": {\n \"profile\": \"jwt role based authorization\"\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"jwt_authentication_local\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Client Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"jwt_type\": \"signed\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"jwt role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] - }, + }, + "response": [] + } + ] + }, + { + "name": "mTLS Client Authentication", + "item": [ { - "name": "HTTP Headers Manipulation", - "item": [ + "name": "HTTPS server with mTLS, OCSP, SSL Stapling", + "event": [ { - "name": "Create test echo service", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"internal_lan\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n },\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"internal_lan\",\n \"address\": \"192.168.2.13\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "NGINX App Protect WAF", + "item": [ + { + "name": "Create initial NGINX configuration with NGINX App Protect WAF", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Change active NGINX App Protect policy", + "event": [ { - "name": "Manipulate headers - server level", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-allowed\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"Production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"Production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Update TLS certificates", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert2.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert2.key\"\n }\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Disable NGINX App Protect WAF", + "event": [ { - "name": "Manipulate headers - location level", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - ], - "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" - }, + }, + "response": [] + } + ] + }, + { + "name": "NGINX Javascript", + "item": [ { - "name": "HTTPS server", - "item": [ + "name": "NGINX Javascript test", + "event": [ { - "name": "TLS Offload", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"Google\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Server-side and source of truth authentication", + "item": [ + { + "name": "Bearer Token, Basic and HTTP header upstream authentication", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"Bearer token-based authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"Bearer token-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Header-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n },\n {\n \"name\": \"Basic authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"type\": \"basic\",\n \"username\": \"authusername\",\n \"password\": \"YXV0aHBhc3N3b3Jk\"\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "TLS Offload and NGINX App Protect", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - GitOps\",\n \"description\": \"This is a production-ready policy - Managed by GitOps\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] + }, + "response": [] }, { - "name": "JWT Client Authentication", - "item": [ + "name": "mTLS upstream authentication", + "event": [ { - "name": "JWT Client Authentication - local JWT key and Bearer token", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"JWT Auth with hardwired key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\"\n }\n },\n {\n \"name\": \"JWT Auth with external key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication GitOps\",\n \"key\": \"http://192.168.2.5:20080/jwks.json\",\n \"cachetime\": 5\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in auth_token query string parameter\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$arg_auth_token\"\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$http_x_auth_token\"\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"client_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZBakNDQStxZ0F3SUJBZ0lVYXZ1aFhBOWFLVFJlYmZ2Y1BFU2Z0MjBUQXhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1ZqRUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlZCQWdNQkVOdmNtc3hEVEFMQmdOVkJBY01CRU52Y21zeApFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUll3RkFZRFZRUUREQTEwWlhOMExtRmpiV1F1YkdGdU1CNFhEVEkwCk1EUXhOVEUzTURnMU0xb1hEVEkxTURReE5URTNNRGcxTTFvd1dERUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlYKQkFnTUJFTnZjbXN4RFRBTEJnTlZCQWNNQkVOdmNtc3hFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUmd3RmdZRApWUVFEREE5amJHbGxiblF1WVdOdFpTNXNZV0l3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLCkFvSUNBUURUQ2kydi8rc08rdTJTcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkQKUWkvL0dIZXhYS3NaelBURDUyN0ZMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOApPa3lxVFdma0xkRnF2akFGclU5czMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2CmpsV1E5NTVWUzlmZlNLU3hpQTRCQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUMKRjYrRGZmQ2FNLzVockljRkswSVFheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNOAo5UlhxQmlaNnFWdGFPQXFEK0pRVGNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4CnZvczA4TSsvOUlhWTdQeGtQNXB6bDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0QKbTlURDJKT0hTU3VmdkRkRnV1YjFwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwegpkZ1RsMDVVWjZtMFpFNUdlK1FRaG5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BCmFLZ0hTbTJROE9MS1lJdlhVN1RpME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzQKc3I0UXJ4Q2xuY2pwbUMrdkRmdHJuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJvNEhGTUlIQwpNQWtHQTFVZEV3UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ1dnTURNR0NXQ0dTQUdHK0VJQkRRUW1GaVJQCmNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRGJHbGxiblFnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZGQmIKdmltZDYxekxLdlA0U2RZRFRWbndYdFVwTUI4R0ExVWRJd1FZTUJhQUZLY29GRHpMVnc1QXBiMzB5UTM0c25MZQpHQ1FWTUE0R0ExVWREd0VCL3dRRUF3SUY0REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVICkF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSmg0cm9kZEVGemJwWk5kSW5zUmdubWVnWVIxSWlzUUxRU0IKcmNydEZxVmtLb3Rsc09EUXBFMThIRjBsbVA4WE9IU0hqYytYUVF5YlFNd1ViZ2RNbnhBZE1WaGFaMXppWElnaQpiUHgwOEY0YXR5MElJY1hyOVpFVnZTd1pheURBZHErb2s5RGpoRjQwYU5iQmFBTXB2NTRCL2U3OUNMSWZ6REo4CnNZaWw3K09abWlOUTJtZUNreVBYdXdhd3hTeVRnNVhWS3Q4VEtKQVJ5aTFJeWRHWkZRMTJGWFJHTE1BSjdaYngKRzlPd1ZvazExenpWNkRQZHFuZU5ER3BQRU5WZ2VmVjI0ZU1JVXUrYzhnSThYTU1GMU9VVWR3MmlEQmU4Q01TQQppc2h2aDFWYVZPNC96czlma2dLV2FXejNwQWprN3pkbWdaUnpXRUVHR0JMekJoQk5FQTg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"client_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRFRDaTJ2LytzTyt1MlMKcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkRRaS8vR0hleFhLc1p6UFRENTI3RgpMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOE9reXFUV2ZrTGRGcXZqQUZyVTlzCjMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2amxXUTk1NVZTOWZmU0tTeGlBNEIKQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUNGNitEZmZDYU0vNWhySWNGSzBJUQpheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNODlSWHFCaVo2cVZ0YU9BcUQrSlFUCmNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4dm9zMDhNKy85SWFZN1B4a1A1cHoKbDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0RtOVREMkpPSFNTdWZ2RGRGdXViMQpwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwemRnVGwwNVVaNm0wWkU1R2UrUVFoCm5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BYUtnSFNtMlE4T0xLWUl2WFU3VGkKME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzRzcjRRcnhDbG5janBtQyt2RGZ0cgpuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJBb0lDQUJzWEZBK2krRmVFbW5rdE9xdHRUL1FsCk5TUlozL05WYjJuRlcyUGRqRHhKcGtUTzV2VS9qYThVd2ZmTVIrdWxCbWhSWkVmOFBweVBMc2J5USszV29iSjAKUk9JQlprVjdYd2ZDWDdEVUJDc0VtS3ZscDlvN3JVQmJqV0w1SmpJNDhYeDI3VFR0NlFMY05uVXhUZDUxanRPagpXYXFJdzNqNU1Oc0tFdDRncWlET2RhQzIvMzJaekZkTHNHNWdnRmRnUElZOUpYUXN3bHk2VnZjdzVpU0RoTnRICkcyYWxYYXdiL2s1Sk9OWTIyY3RDT0kyUnhPUGtPc3lYRkoxYTBRQStGYmxBWExKenVubE5ZNU9iOXEwWTFpa2sKSHpGeXBUcENSdmY2dzY3em00NUYvZVdkS0MzdmpnM29JK29GUS9vMTJUdjhWV3Bhc0ptSmoraUJ5aFRpOGx4YQpMempXaHNrUFZJUGJDYjFDTmIzZHNQSWVWYTVQYmRORGh2bHBQZFV4cXhKRGI4ZUFhemxSQXJVdmtaQnpkTjZtCjVwekljNGtMQnd3Wno5eGg1MzdsQ0tlZ3ZJYmdEMlQvMEM4SVFsWmFIK1M3azlWaVU2Z1RWSGNzU1RsSm52NVYKN3VCMWczVzJZRVloZFJxNlJOUXRZaUFuTktUS2ZYb3d1UUJteWRwVWRYWUljTE5GcER6eHgvRGdQSEhnU0J1dQpQZXVMZzdpemhSSndKMTQ1eW5VTlloQnROVVJaOWlRL1cwWTJOa242UWFBZDNld1pLaVg0S3lZU2k3TTF1MFJWCmFDc1BmZWJrWkRTUnRnQ2Q5N3dGSVYyTVh0UnpXNlpKUUlDWkhHTDVkYkJrNU0xQTI2NnJSYmcvTWZJSE9mdTMKRUZBVjc2aXoyVmNtSDRzblNZUHhBb0lCQVFEc0pNWElhM3ZyRXdRSkh0alRWZE9ONk9rbEExRVN4aWtjSWdSOAo3aFRWQXk3dmtORlpFVUhYczQ1TXlYQzRxTWlvUnFhZHVtOXpQWnFBQ0tQMHRWcXdDMVdOcUFrbDBQc1pZYXcrCmpKNjRDQXA4ZnJ4UDUrOVpWREtiamRWK1ZrK1lrbC9UL0Q1djNFTnZIdkVxN3ZMSE56dE9VSmFWZXNFRERQSW8KaER5SHhjRXQwTHRXTFhoNGNMSDhIQk9Kc0wxYXcxRlhNTk1qdERzazlBMTlJRFlYTHcwaWpIeC81c3hHUGcxSQpmMXRIemhpTlN5NUU5RG9pTmJxVFQvWEEyYVdCdjJ1ZlQybmw2ekticHZHNVo0VGlOUE5ESU5MaUFXOVNNQnJnCkJtaXJFVHU4MnVSa3hnaWZTM01CZ0ZFdXVtaSt2cEhwNzhGaUNOcHpZZUFwTUxjN0FvSUJBUURreVFVT29HVjEKTzZaNXJ4KzhLbVh1S3dmbXNHNmh5cmkrNEw4MzRQakVhbHdkdFhFUmphUG8vSTVhOVFoYjNnLzF5SUdiMzdLSgpPaTFCcGVRZ1owUEVQdFgyRWI0QTNCSTA5SzExWWFybnJGM2d6WS9CVWgveEZoL1YvVEVzTTloZTZ4YlhtRm9WCktvMlY1b2NlNnQzNUJuNHVLL2xkSEJKMHJnUENQdXNKVU9JMEhtUzZkdXNQcHczRFpESkZ5SEU4anptSllwcUsKMnBEMlBBMVZ5aVBBM3MwOU12TWdNSmJXajJLQVBoYk4xQXJnTERaUTFuZ0VwaVFtM3hWdmxIVkMzN0JHM0IzcApWbmtSRE9UZnF1N1BXek40aHZnMDRaNkxBdEZuYzNnMFFxRGcvcXZlS0xuclZwOUJEUlhWb0pZZkNMaVBkajZCCmFiYnFXQ0lYTnMwTkFvSUJBUURFWllrQk9UT2t2UG44UStWOVRzSldJa0hWZ0w2cTZKaEVSNTZIOE5MdW5ta28KNGI3Ylh0anQ5dTRBdXdDKzg5Ris4dE9jRnZTZVdidm5oRWdvTzdTaSthbzcyR2RUUmsyd1BHV3UxL0VoaWI1Kwo4RURhREVJcWZ6WmYzVVNVZ0dCT3VsNXN4anQvZVNlMGdYMStnYUQxUXVCV0wvd3RjaHlZMXVtSC9RTUN3TnY3CnFNQkYyaWQ1cy9Demh2NVE0K2Q0VnoyTlVKUXArN204OENWUHpieHU1N2o2NVBDZXgydFplRDQvNzN3UmFqMU4KTmh2VFNYUVlBNnVhM1VPOUVzYnQ5REFrSFQ0cjlNTHdaWlpnNXRIRCtObmhHS21MUWpvOWxyaWpYWEVyNVhkVAppSkd2cG15Qlg1VFV5TTI4R1ZrSVd5S3I5N1ZVUFp6Qm5jTjdQb01GQW9JQkFDSWRCekFESXAyMFkwSkpwb1c4CkhLN0NvODcyQjhrQUhVUDQ1d3BCOVZYME5nQUlDZkFBR3F5bTIrTWNIajcwZ1pTNGJQcjlBL1lLUXExRE94ekoKeVFUK0NaRkRXLzFzMHhvcVVhTHJDVHk2S3RWV1VWVVdGY1V3ODFaSkJvZjh3d3FFSzBmQ1k4dzhLQmh0NHovcwo3V1F3WDZncXptZmZ3N0M2TWIxSS9HckxNSzlzeU1BMDh4L0dYUHNCZWEyR0VieGg3c1paZVlteXhXS3gyWnN0CkpOK2hXU0VDODlXYzZTRGRDR2J1MngrZHVuRnFwajZ2ZS8zVmVCYUR0UUtLTkdIZ1VMeUFIY1dwS3l3cnJBVGQKeS9ZSE4wbUZkb1VNRDBQVEM3NU5MV005ZkJlUVliZ2lnblpnMkNZdStVNTlQMlVwTzd2SWVkRjZIZGdiaEJuSwpCaEVDZ2dFQkFNZmQ2Zi90RThTQlNFUnd5YW80SThuZkhTZUlMUklvM3pqRE5vWHZ6VHlwbG00a3ovYW9QeEF0CmhPYVNmZU41bFljMXFFUkRxZzRIVGRNTUkyenZPaVFuMHNGTEJFZ0UwT0VIOEZxZVZlZGgycUJucFdXWEhwTW8KREd4TnhpUnVpSDZpOEVMVWFoaU1NQkdQVi9ONjI5MDREbnUyYVVHcHlMTzZxems3SmM5VXlITC90QVNRTFIzagp6NFBhb2xTRE5rNzJSUks0VjIyZUprM2EwYVhjRU5vM1R0OUlTUTliMG5DYVVKbFJsZTA0d2QrOWUyN0FRNUNaCkVWbUtZT1JYcW9VTGNQOEcxRm1VUGhDRkU2aEI3L1hSVWpQdmJFdm5rS05Cdko2UHppT0RMdktRK3I4TzR0WkMKQi9LTDlCdjNmdUkvQlJLeU9WZVU1VnZ5MzUveUFxVT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"mTLS authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"mTLS authentication profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"certificate\": \"client_cert\",\n \"key\": \"client_key\"\n }\n }\n ]\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "JWT secret fetched from URL", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with external key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Stream server", + "item": [ + { + "name": "Create stream server", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"DNS Load Balancer\",\n \"resolver\": \"Quad-ones\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"google_DNS_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"google_DNS_upstream\",\n \"origin\": [\n {\n \"server\": \"ns1.google.com:53\"\n },\n {\n \"server\": \"ns2.google.com:53\"\n }\n ],\n \"resolver\": \"Quad9\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Quad9\",\n \"address\": \"9.9.9.9\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n },\n {\n \"name\": \"Quad-ones\",\n \"address\": \"1.1.1.1\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "NGINX One", + "item": [ + { + "name": "API Gateway", + "item": [ + { + "name": "Ergast API", + "item": [ { - "name": "JWT token in auth_token query string parameter", + "name": "Ergast API Gateway and DevPortal with redocly", "event": [ { "listen": "test", @@ -4195,16 +5730,17 @@ "", "pm.collectionVariables.set('configUid',respData.configUid);" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in auth_token query string parameter\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4212,7 +5748,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -4220,15 +5756,14 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] }, { - "name": "JWT token in HTTP X-Auth-Token header", + "name": "Ergast API Gateway and DevPortal with backstage", "event": [ { "listen": "test", @@ -4240,16 +5775,17 @@ "", "pm.collectionVariables.set('configUid',respData.configUid);" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4257,7 +5793,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -4265,8 +5801,7 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, @@ -4275,109 +5810,296 @@ ] }, { - "name": "JWT Client Authentication and Authorization", + "name": "Petstore API", "item": [ { - "name": "JWT Client Authentication and Authorization", - "event": [ + "name": "API Client test requests", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"JWT AuthN and AuthZ test server\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/auth-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/auth-test.nginx.lab_error_log\"\n },\n \"headers\": {\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-JWT-Group\",\n \"value\": \"$jwt_claim_roles\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"jwt_authentication_local\"\n }\n ]\n },\n \"authorization\": {\n \"profile\": \"jwt role based authorization\"\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"jwt_authentication_local\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Client Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"jwt_type\": \"signed\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"jwt role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Get Inventory (legitimate request)", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + }, + { + "name": "Get Inventory (malicious query string)", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://apigw.nginx.lab/petstore/store/inventory?/etc/passwd", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "store", + "inventory" + ], + "query": [ + { + "key": "/etc/passwd", + "value": null + } + ] + } + }, + "response": [] + }, + { + "name": "Get Inventory (XSS attack)", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + }, + { + "name": "Login without token", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + }, + { + "name": "Login with \"DevOps\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "" + } + }, + "response": [] + }, + { + "name": "Login with \"Guest\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQWxpY2UgR3Vlc3QiLCJzdWIiOiJKV1Qgc3ViIGNsYWltIiwiaXNzIjoiSldUIGlzcyBjbGFpbSIsInJvbGVzIjpbImd1ZXN0Il19.jFJDq-33irz7uFxdI8c8fIb5TwTAU5BlemmIFVALUAE", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "https://apigw.nginx.lab/petstore/user/login", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "user", + "login" + ] + } + }, + "response": [] + }, + { + "name": "Login with dual (DevOps & Guest) role token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIiwiZ3Vlc3QiXX0.3ES7aVquklWqlZ4OWzt8rBz5px4kKZRgvifFVNomCsU", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "https://apigw.nginx.lab/petstore/user/login", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "user", + "login" + ] + } + }, + "response": [] + }, + { + "name": "Upload pet image without token", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" + } + ] + }, + "url": { + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "pet", + "1", + "uploadImage" + ] + } + }, + "response": [] + }, + { + "name": "Upload pet image with \"DevOps\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" + } + ] + }, + "url": { + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "pet", + "1", + "uploadImage" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "mTLS Client Authentication", - "item": [ - { - "name": "HTTPS server with mTLS, OCSP, SSL Stapling", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"192.168.1.13\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" + "name": "Upload pet image with \"Guest\" token", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDk3NjQ3NTMsImV4cCI6MTcwOTc2NDc1NH0.eyJuYW1lIjoiQWxpY2UgR3Vlc3QiLCJzdWIiOiJKV1Qgc3ViIGNsYWltIiwiaXNzIjoiSldUIGlzcyBjbGFpbSIsInJvbGVzIjpbImd1ZXN0Il19.jFJDq-33irz7uFxdI8c8fIb5TwTAU5BlemmIFVALUAE", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "file", + "value": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TS0UqChYRcchQXbSLijjWKhShQqgVWnUwuX5Ck4YkxcVRcC04+LFYdXBx1tXBVRAEP0CcHZwUXaTE/yWFFjEeHPfj3b3H3TtAaFSYanbFAFWzjFQiLmayq2LwFQEI6Mc4BmVm6nOSlITn+LqHj693UZ7lfe7P0ZvLmwzwicQxphsW8QbxzKalc94nDrOSnCM+J54w6ILEj1xXXH7jXHRY4JlhI52aJw4Ti8UOVjqYlQyVeJo4klM1yhcyLuc4b3FWKzXWuid/YSivrSxzneYIEljEEiSIUFBDGRVYiNKqkWIiRftxD/+w45fIpZCrDEaOBVShQnb84H/wu1uzMDXpJoXiQODFtj9GgeAu0Kzb9vexbTdPAP8zcKW1/dUGMPtJer2tRY6Avm3g4rqtKXvA5Q4w9KTLhuxIfppCoQC8n9E3ZYGBW6Bnze2ttY/TByBNXSVvgINDYKxI2ese7+7u7O3fM63+fgB5bXKpzZcBIwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+gFAhArKAvJglcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC", + "type": "text" + }, + { + "key": "type", + "value": "image/png", + "type": "text" + } + ] + }, + "url": { + "raw": "https://apigw.nginx.lab/petstore/pet/1/uploadImage", + "protocol": "https", + "host": [ + "apigw", + "nginx", + "lab" + ], + "path": [ + "petstore", + "pet", + "1", + "uploadImage" + ] } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + }, + "response": [] } - }, - "response": [] - } - ] - }, - { - "name": "NGINX App Protect WAF", - "item": [ + ], + "description": "This folder contains requests to access the Petstore API published through NGINX using the Declarative API" + }, { - "name": "Create initial NGINX configuration with NGINX App Protect WAF", + "name": "Petstore API Gateway RateLimit", "event": [ { "listen": "test", @@ -4399,7 +6121,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-blocked\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"This is a production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"This is a production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ],\n \"app_protect\": {\n \"enabled\": true,\n \"policy\": \"production-policy\",\n \"log\": {\n \"profile_name\": \"secops_dashboard\",\n \"enabled\": true,\n \"destination\": \"127.0.0.1:514\"\n }\n }\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4422,53 +6144,7 @@ "response": [] }, { - "name": "Change active NGINX App Protect policy", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"policies\": [\n {\n \"type\": \"app_protect\",\n \"name\": \"production-policy\",\n \"active_tag\": \"xss-allowed\",\n \"versions\": [\n {\n \"tag\": \"xss-blocked\",\n \"displayName\": \"Production Policy - XSS blocked\",\n \"description\": \"Production-ready policy - XSS blocked\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-blocked.json\"\n }\n },\n {\n \"tag\": \"xss-allowed\",\n \"displayName\": \"Production Policy - XSS allowed\",\n \"description\": \"Production-ready policy - XSS allowed\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/nap-policy-xss-allowed.json\"\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, - { - "name": "Update TLS certificates", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", "event": [ { "listen": "test", @@ -4486,11 +6162,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_app_protect_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert2.key\"\n }\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4498,7 +6174,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -4506,15 +6182,14 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] }, { - "name": "Disable NGINX App Protect WAF", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", "event": [ { "listen": "test", @@ -4531,62 +6206,12 @@ } } ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "NGINX Javascript", - "item": [ - { - "name": "NGINX Javascript test", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript" - } - } - ], "request": { "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4607,14 +6232,9 @@ } }, "response": [] - } - ] - }, - { - "name": "Server-side and source of truth authentication", - "item": [ + }, { - "name": "Bearer Token, Basic and HTTP header upstream authentication", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly + moesif", "event": [ { "listen": "test", @@ -4636,7 +6256,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"Bearer token-based authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"Bearer token-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Header-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n },\n {\n \"name\": \"Basic authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"type\": \"basic\",\n \"username\": \"authusername\",\n \"password\": \"YXV0aHBhc3N3b3Jk\"\n }\n }\n ]\n }\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ndk_http_module\",\n \"ngx_http_lua_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"visibility\": [\n {\n \"enabled\": true,\n \"type\": \"moesif\",\n \"moesif\": {\n \"application_id\": \"{{moesif_application_id}}\"\n }\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4659,7 +6279,7 @@ "response": [] }, { - "name": "mTLS upstream authentication", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", "event": [ { "listen": "test", @@ -4681,7 +6301,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v2/www.online-boutique.local.key\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"client_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZBakNDQStxZ0F3SUJBZ0lVYXZ1aFhBOWFLVFJlYmZ2Y1BFU2Z0MjBUQXhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1ZqRUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlZCQWdNQkVOdmNtc3hEVEFMQmdOVkJBY01CRU52Y21zeApFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUll3RkFZRFZRUUREQTEwWlhOMExtRmpiV1F1YkdGdU1CNFhEVEkwCk1EUXhOVEUzTURnMU0xb1hEVEkxTURReE5URTNNRGcxTTFvd1dERUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlYKQkFnTUJFTnZjbXN4RFRBTEJnTlZCQWNNQkVOdmNtc3hFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUmd3RmdZRApWUVFEREE5amJHbGxiblF1WVdOdFpTNXNZV0l3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLCkFvSUNBUURUQ2kydi8rc08rdTJTcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkQKUWkvL0dIZXhYS3NaelBURDUyN0ZMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOApPa3lxVFdma0xkRnF2akFGclU5czMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2CmpsV1E5NTVWUzlmZlNLU3hpQTRCQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUMKRjYrRGZmQ2FNLzVockljRkswSVFheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNOAo5UlhxQmlaNnFWdGFPQXFEK0pRVGNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4CnZvczA4TSsvOUlhWTdQeGtQNXB6bDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0QKbTlURDJKT0hTU3VmdkRkRnV1YjFwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwegpkZ1RsMDVVWjZtMFpFNUdlK1FRaG5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BCmFLZ0hTbTJROE9MS1lJdlhVN1RpME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzQKc3I0UXJ4Q2xuY2pwbUMrdkRmdHJuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJvNEhGTUlIQwpNQWtHQTFVZEV3UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ1dnTURNR0NXQ0dTQUdHK0VJQkRRUW1GaVJQCmNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRGJHbGxiblFnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZGQmIKdmltZDYxekxLdlA0U2RZRFRWbndYdFVwTUI4R0ExVWRJd1FZTUJhQUZLY29GRHpMVnc1QXBiMzB5UTM0c25MZQpHQ1FWTUE0R0ExVWREd0VCL3dRRUF3SUY0REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVICkF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSmg0cm9kZEVGemJwWk5kSW5zUmdubWVnWVIxSWlzUUxRU0IKcmNydEZxVmtLb3Rsc09EUXBFMThIRjBsbVA4WE9IU0hqYytYUVF5YlFNd1ViZ2RNbnhBZE1WaGFaMXppWElnaQpiUHgwOEY0YXR5MElJY1hyOVpFVnZTd1pheURBZHErb2s5RGpoRjQwYU5iQmFBTXB2NTRCL2U3OUNMSWZ6REo4CnNZaWw3K09abWlOUTJtZUNreVBYdXdhd3hTeVRnNVhWS3Q4VEtKQVJ5aTFJeWRHWkZRMTJGWFJHTE1BSjdaYngKRzlPd1ZvazExenpWNkRQZHFuZU5ER3BQRU5WZ2VmVjI0ZU1JVXUrYzhnSThYTU1GMU9VVWR3MmlEQmU4Q01TQQppc2h2aDFWYVZPNC96czlma2dLV2FXejNwQWprN3pkbWdaUnpXRUVHR0JMekJoQk5FQTg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"client_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRFRDaTJ2LytzTyt1MlMKcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkRRaS8vR0hleFhLc1p6UFRENTI3RgpMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOE9reXFUV2ZrTGRGcXZqQUZyVTlzCjMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2amxXUTk1NVZTOWZmU0tTeGlBNEIKQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUNGNitEZmZDYU0vNWhySWNGSzBJUQpheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNODlSWHFCaVo2cVZ0YU9BcUQrSlFUCmNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4dm9zMDhNKy85SWFZN1B4a1A1cHoKbDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0RtOVREMkpPSFNTdWZ2RGRGdXViMQpwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwemRnVGwwNVVaNm0wWkU1R2UrUVFoCm5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BYUtnSFNtMlE4T0xLWUl2WFU3VGkKME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzRzcjRRcnhDbG5janBtQyt2RGZ0cgpuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJBb0lDQUJzWEZBK2krRmVFbW5rdE9xdHRUL1FsCk5TUlozL05WYjJuRlcyUGRqRHhKcGtUTzV2VS9qYThVd2ZmTVIrdWxCbWhSWkVmOFBweVBMc2J5USszV29iSjAKUk9JQlprVjdYd2ZDWDdEVUJDc0VtS3ZscDlvN3JVQmJqV0w1SmpJNDhYeDI3VFR0NlFMY05uVXhUZDUxanRPagpXYXFJdzNqNU1Oc0tFdDRncWlET2RhQzIvMzJaekZkTHNHNWdnRmRnUElZOUpYUXN3bHk2VnZjdzVpU0RoTnRICkcyYWxYYXdiL2s1Sk9OWTIyY3RDT0kyUnhPUGtPc3lYRkoxYTBRQStGYmxBWExKenVubE5ZNU9iOXEwWTFpa2sKSHpGeXBUcENSdmY2dzY3em00NUYvZVdkS0MzdmpnM29JK29GUS9vMTJUdjhWV3Bhc0ptSmoraUJ5aFRpOGx4YQpMempXaHNrUFZJUGJDYjFDTmIzZHNQSWVWYTVQYmRORGh2bHBQZFV4cXhKRGI4ZUFhemxSQXJVdmtaQnpkTjZtCjVwekljNGtMQnd3Wno5eGg1MzdsQ0tlZ3ZJYmdEMlQvMEM4SVFsWmFIK1M3azlWaVU2Z1RWSGNzU1RsSm52NVYKN3VCMWczVzJZRVloZFJxNlJOUXRZaUFuTktUS2ZYb3d1UUJteWRwVWRYWUljTE5GcER6eHgvRGdQSEhnU0J1dQpQZXVMZzdpemhSSndKMTQ1eW5VTlloQnROVVJaOWlRL1cwWTJOa242UWFBZDNld1pLaVg0S3lZU2k3TTF1MFJWCmFDc1BmZWJrWkRTUnRnQ2Q5N3dGSVYyTVh0UnpXNlpKUUlDWkhHTDVkYkJrNU0xQTI2NnJSYmcvTWZJSE9mdTMKRUZBVjc2aXoyVmNtSDRzblNZUHhBb0lCQVFEc0pNWElhM3ZyRXdRSkh0alRWZE9ONk9rbEExRVN4aWtjSWdSOAo3aFRWQXk3dmtORlpFVUhYczQ1TXlYQzRxTWlvUnFhZHVtOXpQWnFBQ0tQMHRWcXdDMVdOcUFrbDBQc1pZYXcrCmpKNjRDQXA4ZnJ4UDUrOVpWREtiamRWK1ZrK1lrbC9UL0Q1djNFTnZIdkVxN3ZMSE56dE9VSmFWZXNFRERQSW8KaER5SHhjRXQwTHRXTFhoNGNMSDhIQk9Kc0wxYXcxRlhNTk1qdERzazlBMTlJRFlYTHcwaWpIeC81c3hHUGcxSQpmMXRIemhpTlN5NUU5RG9pTmJxVFQvWEEyYVdCdjJ1ZlQybmw2ekticHZHNVo0VGlOUE5ESU5MaUFXOVNNQnJnCkJtaXJFVHU4MnVSa3hnaWZTM01CZ0ZFdXVtaSt2cEhwNzhGaUNOcHpZZUFwTUxjN0FvSUJBUURreVFVT29HVjEKTzZaNXJ4KzhLbVh1S3dmbXNHNmh5cmkrNEw4MzRQakVhbHdkdFhFUmphUG8vSTVhOVFoYjNnLzF5SUdiMzdLSgpPaTFCcGVRZ1owUEVQdFgyRWI0QTNCSTA5SzExWWFybnJGM2d6WS9CVWgveEZoL1YvVEVzTTloZTZ4YlhtRm9WCktvMlY1b2NlNnQzNUJuNHVLL2xkSEJKMHJnUENQdXNKVU9JMEhtUzZkdXNQcHczRFpESkZ5SEU4anptSllwcUsKMnBEMlBBMVZ5aVBBM3MwOU12TWdNSmJXajJLQVBoYk4xQXJnTERaUTFuZ0VwaVFtM3hWdmxIVkMzN0JHM0IzcApWbmtSRE9UZnF1N1BXek40aHZnMDRaNkxBdEZuYzNnMFFxRGcvcXZlS0xuclZwOUJEUlhWb0pZZkNMaVBkajZCCmFiYnFXQ0lYTnMwTkFvSUJBUURFWllrQk9UT2t2UG44UStWOVRzSldJa0hWZ0w2cTZKaEVSNTZIOE5MdW5ta28KNGI3Ylh0anQ5dTRBdXdDKzg5Ris4dE9jRnZTZVdidm5oRWdvTzdTaSthbzcyR2RUUmsyd1BHV3UxL0VoaWI1Kwo4RURhREVJcWZ6WmYzVVNVZ0dCT3VsNXN4anQvZVNlMGdYMStnYUQxUXVCV0wvd3RjaHlZMXVtSC9RTUN3TnY3CnFNQkYyaWQ1cy9Demh2NVE0K2Q0VnoyTlVKUXArN204OENWUHpieHU1N2o2NVBDZXgydFplRDQvNzN3UmFqMU4KTmh2VFNYUVlBNnVhM1VPOUVzYnQ5REFrSFQ0cjlNTHdaWlpnNXRIRCtObmhHS21MUWpvOWxyaWpYWEVyNVhkVAppSkd2cG15Qlg1VFV5TTI4R1ZrSVd5S3I5N1ZVUFp6Qm5jTjdQb01GQW9JQkFDSWRCekFESXAyMFkwSkpwb1c4CkhLN0NvODcyQjhrQUhVUDQ1d3BCOVZYME5nQUlDZkFBR3F5bTIrTWNIajcwZ1pTNGJQcjlBL1lLUXExRE94ekoKeVFUK0NaRkRXLzFzMHhvcVVhTHJDVHk2S3RWV1VWVVdGY1V3ODFaSkJvZjh3d3FFSzBmQ1k4dzhLQmh0NHovcwo3V1F3WDZncXptZmZ3N0M2TWIxSS9HckxNSzlzeU1BMDh4L0dYUHNCZWEyR0VieGg3c1paZVlteXhXS3gyWnN0CkpOK2hXU0VDODlXYzZTRGRDR2J1MngrZHVuRnFwajZ2ZS8zVmVCYUR0UUtLTkdIZ1VMeUFIY1dwS3l3cnJBVGQKeS9ZSE4wbUZkb1VNRDBQVEM3NU5MV005ZkJlUVliZ2lnblpnMkNZdStVNTlQMlVwTzd2SWVkRjZIZGdiaEJuSwpCaEVDZ2dFQkFNZmQ2Zi90RThTQlNFUnd5YW80SThuZkhTZUlMUklvM3pqRE5vWHZ6VHlwbG00a3ovYW9QeEF0CmhPYVNmZU41bFljMXFFUkRxZzRIVGRNTUkyenZPaVFuMHNGTEJFZ0UwT0VIOEZxZVZlZGgycUJucFdXWEhwTW8KREd4TnhpUnVpSDZpOEVMVWFoaU1NQkdQVi9ONjI5MDREbnUyYVVHcHlMTzZxems3SmM5VXlITC90QVNRTFIzagp6NFBhb2xTRE5rNzJSUks0VjIyZUprM2EwYVhjRU5vM1R0OUlTUTliMG5DYVVKbFJsZTA0d2QrOWUyN0FRNUNaCkVWbUtZT1JYcW9VTGNQOEcxRm1VUGhDRkU2aEI3L1hSVWpQdmJFdm5rS05Cdko2UHppT0RMdktRK3I4TzR0WkMKQi9LTDlCdjNmdUkvQlJLeU9WZVU1VnZ5MzUveUFxVT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"mTLS authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"mTLS authentication profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"certificate\": \"client_cert\",\n \"key\": \"client_key\"\n }\n }\n ]\n }\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -4708,856 +6328,847 @@ ] }, { - "name": "NGINX One", + "name": "CRUD automation", "item": [ { - "name": "API Gateway", - "item": [ + "name": "Create initial NGINX configuration", + "event": [ { - "name": "Ergast API", - "item": [ - { - "name": "Ergast API Gateway and DevPortal with redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Ergast API Gateway and DevPortal with backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"api-team\",\n \"system\": \"public-api-system\"\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Update HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Modify and add HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add stream server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" ] + } + }, + "response": [] + }, + { + "name": "Remove HTTP server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add Stream server and upstream", + "event": [ { - "name": "Petstore API", - "item": [ - { - "name": "Petstore API Gateway RateLimit", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:80\",\n \"http2\": true\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, - { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"8.8.8.8\",\n \"listen\": {\n \"address\": \"0.0.0.0:80\",\n \"http2\": true\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #2", + "event": [ { - "name": "Petstore & Ergast API Gateway all in one", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Housekeeping - common endpoints", + "item": [ + { + "name": "Clean NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore and Ergast API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"192.168.2.13\",\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n },\n {\n \"uri\": \"/ergast\",\n \"urimatch\": \"prefix\",\n \"snippet\": {\n \"content\": \"IyBUZXN0IFNOSVBQRVQK\"\n },\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"https://raw.githubusercontent.com/adampax/ergast-f1-openapi-doc/e558eea18e176e4f78a8765ac7eccc804b5157ff/ergast-openapi-doc.yaml\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/ergast-devportal.html\"\n }\n },\n \"rate_limit\": [\n {\n \"profile\": \"ergast_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0\n }\n ],\n \"log\": {\n \"access\": \"/var/log/nginx/ergast-access_log\",\n \"error\": \"/var/log/nginx/ergast-error_log\"\n }\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"ergast_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"1r/s\"\n },\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] } - ] + }, + "response": [] }, { - "name": "CRUD automation", - "item": [ + "name": "Get declaration", + "event": [ { - "name": "Create initial NGINX configuration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - ] + }, + "response": [] }, { - "name": "Housekeeping - common endpoints", - "item": [ - { - "name": "Clean NGINX configuration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\"\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] - }, + "name": "Delete declaration", + "event": [ { - "name": "Get declaration status", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}", - "status" - ] + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "Get declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "HTTP Headers Manipulation", + "item": [ + { + "name": "Create test echo service", + "event": [ { - "name": "Delete declaration", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "DELETE", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] + }, + "response": [] }, { - "name": "HTTP Headers Manipulation", - "item": [ + "name": "Manipulate headers - server level", + "event": [ { - "name": "Create test echo service", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, - { - "name": "Manipulate headers - server level", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] - }, + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Manipulate headers - location level", + "event": [ { - "name": "Manipulate headers - location level", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.details.message.configUid] = respData.details.message.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.details.message.configUid);" - ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "PATCH", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"resolver\": \"8.8.8.8\",\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config", - "{{configUid}}" - ] - } - }, - "response": [] + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } } ], - "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" - }, + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ], + "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" + }, + { + "name": "HTTPS server", + "item": [ { - "name": "HTTPS server", - "item": [ + "name": "TLS Offload", + "event": [ { - "name": "TLS Offload", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/v4.2/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] - }, + }, + "response": [] + } + ] + }, + { + "name": "mTLS Client Authentication", + "item": [ { - "name": "mTLS Client Authentication", - "item": [ + "name": "HTTPS server with mTLS, OCSP, SSL Stapling", + "event": [ { - "name": "HTTPS server with mTLS, OCSP, SSL Stapling", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"private DNS\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n },\n \"resolvers\": [\n {\n \"name\": \"private DNS\",\n \"address\": \"192.168.2.13\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"192.168.1.13\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] - }, + }, + "response": [] + } + ] + }, + { + "name": "NGINX Javascript", + "item": [ { - "name": "NGINX Javascript", - "item": [ + "name": "NGINX Javascript test", + "event": [ { - "name": "NGINX Javascript test", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"Google\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"cluster\": \"{{nginxone_clustername}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"8.8.8.8\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] - } - }, - "response": [] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] } - ] + }, + "response": [] } ] } @@ -5567,7 +7178,7 @@ "description": "[https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v5.0.md](https://github.com/f5devcentral/NGINX-Declarative-API/blob/main/USAGE-v4.2.md)" }, { - "name": "v5.1", + "name": "v5.2", "item": [ { "name": "NGINX Instance Manager", @@ -5680,7 +7291,10 @@ "name": "Get Inventory (legitimate request)", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -5716,7 +7330,10 @@ "name": "Get Inventory (XSS attack)", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -5724,7 +7341,10 @@ "name": "Login without token", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -5742,7 +7362,10 @@ ] }, "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -7807,6 +9430,56 @@ } ] }, + { + "name": "NGINX R33+ example", + "item": [ + { + "name": "NGINX R33+ example with usage tracking", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nms\",\n \"nms\": {\n \"url\": \"{{nim_host}}\",\n \"username\": \"{{nim_username}}\",\n \"password\": \"{{nim_password}}\",\n \"instancegroup\": \"{{nim_instancegroup}}\",\n \"synctime\": 0\n },\n \"license\": {\n \"endpoint\": \"{{nginx_reporting_server\",\n \"token\": \"{{nginx_license_token}}\",\n \"ssl_verify\": false,\n \"grace_period\": false\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + }, { "name": "Server-side and source of truth authentication", "item": [ @@ -7955,7 +9628,7 @@ ] }, { - "name": "NGINX One", + "name": "NGINX One Console", "item": [ { "name": "API Gateway", @@ -8065,7 +9738,10 @@ "name": "Get Inventory (legitimate request)", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -8101,7 +9777,10 @@ "name": "Get Inventory (XSS attack)", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -8109,7 +9788,10 @@ "name": "Login without token", "request": { "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -8127,7 +9809,10 @@ ] }, "method": "GET", - "header": [] + "header": [], + "url": { + "raw": "" + } }, "response": [] }, @@ -8329,11 +10014,146 @@ }, "response": [] } - ], - "description": "This folder contains requests to access the Petstore API published through NGINX using the Declarative API" + ], + "description": "This folder contains requests to access the Petstore API published through NGINX using the Declarative API" + }, + { + "name": "Petstore API Gateway RateLimit", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] }, { - "name": "Petstore API Gateway RateLimit", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly + moesif", "event": [ { "listen": "test", @@ -8355,7 +10175,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ndk_http_module\",\n \"ngx_http_lua_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"visibility\": [\n {\n \"enabled\": true,\n \"type\": \"moesif\",\n \"moesif\": {\n \"application_id\": \"{{moesif_application_id}}\"\n }\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -8378,7 +10198,7 @@ "response": [] }, { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ", + "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", "event": [ { "listen": "test", @@ -8395,177 +10215,594 @@ } } ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\",\n \"authentication\": [\n {\n \"profile\": \"Source of truth authentication profile using HTTP header token authentication\"\n }\n ]\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ],\n \"server\": [\n {\n \"name\": \"Source of truth authentication profile using bearer token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Source of truth authentication profile using HTTP header token authentication\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "CRUD automation", + "item": [ + { + "name": "Create initial NGINX configuration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Update HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Modify and add HTTP upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add stream server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove HTTP server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Add Stream server and upstream", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #1", + "event": [ { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove stream server and upstream #2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "GitOps autosync", + "item": [ + { + "name": "NGINX Plus and GitOps", + "event": [ { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + redocly + moesif", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ndk_http_module\",\n \"ngx_http_lua_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"redocly\",\n \"redocly\": {\n \"uri\": \"/petstore-devportal.html\"\n }\n },\n \"visibility\": [\n {\n \"enabled\": true,\n \"type\": \"moesif\",\n \"moesif\": {\n \"application_id\": \"{{moesif_application_id}}\"\n }\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration", + "event": [ { - "name": "Petstore API Gateway RateLimit + JWT AuthN/AuthZ + backstage", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" - ], - "type": "text/javascript", - "packages": {} - } + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Petstore API\",\n \"names\": [\n \"apigw.nginx.lab\"\n ],\n \"resolver\": \"Google\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/apigw.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/apigw.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/petstore\",\n \"urimatch\": \"prefix\",\n \"apigateway\": {\n \"openapi_schema\": {\n \"content\": \"http://petstore.swagger.io/v2/swagger.json\"\n },\n \"api_gateway\": {\n \"enabled\": true,\n \"strip_uri\": true,\n \"server_url\": \"https://petstore.swagger.io/v2\"\n },\n \"developer_portal\": {\n \"enabled\": true,\n \"type\": \"backstage\",\n \"backstage\": {\n \"name\": \"petstore-devportal\",\n \"lifecycle\": \"production\",\n \"owner\": \"Petstore-API-owner\",\n \"system\": \"Public-facing-API-system\"\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"Petstore JWT Authentication\"\n }\n ],\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n },\n \"authorization\": [\n {\n \"profile\": \"JWT role based authorization\",\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"profile\": \"petstore_ratelimit\",\n \"httpcode\": 429,\n \"burst\": 0,\n \"delay\": 0,\n \"enforceOnPaths\": true,\n \"paths\": [\n \"/user/login\",\n \"/user/logout\",\n \"/pet/{petId}/uploadImage\"\n ]\n }\n ]\n },\n \"log\": {\n \"access\": \"/var/log/nginx/petstore-access_log\",\n \"error\": \"/var/log/nginx/petstore-error_log\"\n }\n }\n ]\n }\n ],\n \"rate_limit\": [\n {\n \"name\": \"petstore_ratelimit\",\n \"key\": \"$binary_remote_addr\",\n \"size\": \"10m\",\n \"rate\": \"2r/s\"\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"Petstore JWT Authentication\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"Petstore Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"cachetime\": 5\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"JWT role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ],\n \"errorcode\": 403\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", - "protocol": "http", - "host": [ - "{{ncg_host}}" - ], - "port": "{{ncg_port}}", - "path": [ - "{{ngc_api_version}}", - "config" - ] + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] + } + }, + "response": [] + }, + { + "name": "Delete declaration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" } - }, - "response": [] + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config", + "{{configUid}}" + ] } - ] + }, + "response": [] } ] }, { - "name": "CRUD automation", + "name": "Housekeeping - common endpoints", "item": [ { - "name": "Create initial NGINX configuration", + "name": "Clean NGINX configuration", "event": [ { "listen": "test", @@ -8583,11 +10820,54 @@ } ], "request": { - "method": "POST", + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "protocol": "http", + "host": [ + "{{ncg_host}}" + ], + "port": "{{ncg_port}}", + "path": [ + "{{ngc_api_version}}", + "config" + ] + } + }, + "response": [] + }, + { + "name": "Get declaration status", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\",\n \"names\": [\n \"patched_server.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"127.0.0.1:8080\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/access_log\",\n \"error\": \"/var/log/nginx/error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n }\n }\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -8595,7 +10875,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", "protocol": "http", "host": [ "{{ncg_host}}" @@ -8603,36 +10883,36 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config" + "config", + "{{configUid}}", + "status" ] } }, "response": [] }, { - "name": "Update HTTP upstream", + "name": "Get declaration", "event": [ { "listen": "test", "script": { "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" + "" ], - "type": "text/javascript", - "packages": {} + "type": "text/javascript" } } ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, "request": { - "method": "PATCH", + "method": "GET", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n },\n {\n \"server\": \"10.0.0.3:80\"\n },\n {\n \"server\": \"10.0.0.4:80\"\n },\n {\n \"server\": \"10.0.0.5:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -8656,29 +10936,24 @@ "response": [] }, { - "name": "Modify and add HTTP upstream", + "name": "Delete declaration", "event": [ { "listen": "test", "script": { "exec": [ - "var respData = JSON.parse(responseBody);", - "", - "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", - "", - "pm.collectionVariables.set('configUid',respData.configUid);" + "" ], - "type": "text/javascript", - "packages": {} + "type": "text/javascript" } } ], "request": { - "method": "PATCH", + "method": "DELETE", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:80\"\n },\n {\n \"server\": \"10.0.0.2:80\"\n }\n ]\n },\n {\n \"name\": \"test_upstream_added\",\n \"origin\": [\n {\n \"server\": \"192.168.1.1:80\"\n },\n {\n \"server\": \"192.168.1.2:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "", "options": { "raw": { "language": "json" @@ -8700,9 +10975,14 @@ } }, "response": [] - }, + } + ] + }, + { + "name": "HTTP Headers Manipulation", + "item": [ { - "name": "Add stream server and upstream", + "name": "Create test echo service", "event": [ { "listen": "test", @@ -8720,11 +11000,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\",\n \"listen\": {\n \"address\": \"15432\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_15432_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\",\n \"origin\": [\n {\n \"server\": \"172.16.10.1:5432\"\n },\n {\n \"server\": \"172.16.10.1:5432\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -8732,7 +11012,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -8740,15 +11020,14 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] }, { - "name": "Remove HTTP server and upstream", + "name": "Manipulate headers - server level", "event": [ { "listen": "test", @@ -8770,7 +11049,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"HTTP test application\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream_added\"\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -8794,7 +11073,7 @@ "response": [] }, { - "name": "Add Stream server and upstream", + "name": "Manipulate headers - location level", "event": [ { "listen": "test", @@ -8816,7 +11095,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"tcp\"\n },\n \"upstream\": \"TCP_10053_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\",\n \"origin\": [\n {\n \"server\": \"10.0.0.1:53\"\n },\n {\n \"server\": \"10.0.0.2:53\"\n },\n {\n \"server\": \"10.0.0.3:53\"\n },\n {\n \"server\": \"10.0.0.4:53\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -8838,9 +11117,15 @@ } }, "response": [] - }, + } + ], + "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" + }, + { + "name": "HTTPS server", + "item": [ { - "name": "Remove stream server and upstream #1", + "name": "TLS Offload", "event": [ { "listen": "test", @@ -8858,11 +11143,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_10053_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_10053_upstream\"\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -8870,7 +11155,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -8878,15 +11163,19 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] - }, + } + ] + }, + { + "name": "JWT Client Authentication", + "item": [ { - "name": "Remove stream server and upstream #2", + "name": "JWT Client Authentication - local JWT key and Bearer token", "event": [ { "listen": "test", @@ -8904,11 +11193,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"TCP_15432_service\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"TCP_15432_upstream\"\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"JWT Auth with hardwired key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\"\n }\n },\n {\n \"name\": \"JWT Auth with external key and Bearer token\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication GitOps\",\n \"key\": \"http://192.168.2.5:20080/jwks.json\",\n \"cachetime\": 5\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in auth_token query string parameter\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$arg_auth_token\"\n }\n },\n {\n \"name\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"token_location\": \"$http_x_auth_token\"\n }\n }\n ]\n },\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -8916,7 +11205,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -8924,20 +11213,14 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] - } - ] - }, - { - "name": "Housekeeping - common endpoints", - "item": [ + }, { - "name": "Clean NGINX configuration", + "name": "JWT secret fetched from URL", "event": [ { "listen": "test", @@ -8955,11 +11238,11 @@ } ], "request": { - "method": "POST", + "method": "PATCH", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\"\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with external key and Bearer token\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -8967,7 +11250,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", "protocol": "http", "host": [ "{{ncg_host}}" @@ -8975,34 +11258,37 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config" + "config", + "{{configUid}}" ] } }, "response": [] }, { - "name": "Get declaration status", + "name": "JWT token in auth_token query string parameter", "event": [ { "listen": "test", "script": { "exec": [ - "" + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { - "method": "GET", + "method": "PATCH", "header": [], "body": { "mode": "raw", - "raw": "", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in auth_token query string parameter\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -9010,7 +11296,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}/status", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", "protocol": "http", "host": [ "{{ncg_host}}" @@ -9019,35 +11305,36 @@ "path": [ "{{ngc_api_version}}", "config", - "{{configUid}}", - "status" + "{{configUid}}" ] } }, "response": [] }, { - "name": "Get declaration", + "name": "JWT token in HTTP X-Auth-Token header", "event": [ { "listen": "test", "script": { "exec": [ - "" + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], - "protocolProfileBehavior": { - "disableBodyPruning": true - }, "request": { - "method": "GET", + "method": "PATCH", "header": [], "body": { "mode": "raw", - "raw": "", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test service\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test.nginx.lab-access_log\",\n \"error\": \"/var/log/nginx/test.nginx.lab-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"JWT Auth with hardwired key and token in X-Auth-Token HTTP header\"\n }\n ]\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ]\n }\n }\n}", "options": { "raw": { "language": "json" @@ -9069,26 +11356,36 @@ } }, "response": [] - }, + } + ] + }, + { + "name": "JWT Client Authentication and Authorization", + "item": [ { - "name": "Delete declaration", + "name": "JWT Client Authentication and Authorization", "event": [ { "listen": "test", "script": { "exec": [ - "" + "var respData = JSON.parse(responseBody);", + "", + "tests[\"configUid is: \" +respData.configUid] = respData.configUid;", + "", + "pm.collectionVariables.set('configUid',respData.configUid);" ], - "type": "text/javascript" + "type": "text/javascript", + "packages": {} } } ], "request": { - "method": "DELETE", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"JWT AuthN and AuthZ test server\",\n \"resolver\": \"Google\",\n \"names\": [\n \"test.nginx.lab\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/auth-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/auth-test.nginx.lab_error_log\"\n },\n \"headers\": {\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-JWT-Group\",\n \"value\": \"$jwt_claim_roles\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"jwt_authentication_local\"\n }\n ]\n },\n \"authorization\": {\n \"profile\": \"jwt role based authorization\"\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"jwt_authentication_local\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"realm\": \"JWT Client Authentication\",\n \"key\": \"{\\\"keys\\\": [{\\\"k\\\":\\\"ZmFudGFzdGljand0\\\",\\\"kty\\\":\\\"oct\\\",\\\"kid\\\":\\\"0001\\\"}]}\",\n \"jwt_type\": \"signed\"\n }\n }\n ]\n },\n \"authorization\": [\n {\n \"name\": \"jwt role based authorization\",\n \"type\": \"jwt\",\n \"jwt\": {\n \"claims\": [\n {\n \"name\": \"roles\",\n \"value\": [\n \"~(devops)\"\n ]\n }\n ]\n }\n }\n ],\n \"nginx_plus_api\": {\n \"write\": false,\n \"listen\": \"127.0.0.1:8080\",\n \"allow_acl\": \"0.0.0.0/0\"\n }\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -9096,7 +11393,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -9104,8 +11401,7 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, @@ -9114,10 +11410,10 @@ ] }, { - "name": "HTTP Headers Manipulation", + "name": "mTLS Client Authentication", "item": [ { - "name": "Create test echo service", + "name": "HTTPS server with mTLS, OCSP, SSL Stapling", "event": [ { "listen": "test", @@ -9139,7 +11435,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"private DNS\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n },\n \"resolvers\": [\n {\n \"name\": \"private DNS\",\n \"address\": \"192.168.2.13\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -9160,9 +11456,14 @@ } }, "response": [] - }, + } + ] + }, + { + "name": "NGINX Javascript", + "item": [ { - "name": "Manipulate headers - server level", + "name": "NGINX Javascript test", "event": [ { "listen": "test", @@ -9180,11 +11481,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"Google\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -9192,7 +11493,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -9200,15 +11501,19 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] - }, + } + ] + }, + { + "name": "NGINX R33+ example", + "item": [ { - "name": "Manipulate headers - location level", + "name": "NGINX R33+ example with usage tracking", "event": [ { "listen": "test", @@ -9226,11 +11531,11 @@ } ], "request": { - "method": "PATCH", + "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-Injected-Echo-Test-Version\",\n \"value\": \"v1\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ],\n \"delete\": [\n \"User-Agent\"\n ]\n },\n \"to_client\": {\n \"add\": [\n {\n \"name\": \"X-Injected-Response-Status\",\n \"value\": \"$status\"\n }\n ],\n \"delete\": [\n \"vary\"\n ],\n \"replace\": [\n {\n \"name\": \"Server\",\n \"value\": \"Echo Test Server\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": []\n },\n \"license\": {\n \"endpoint\": \"{{nginx_reporting_server\",\n \"token\": \"{{nginx_license_token}}\",\n \"ssl_verify\": false,\n \"grace_period\": false\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Test echo app\",\n \"names\": [\n \"echo.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/test-echo-access_log\",\n \"error\": \"/var/log/nginx/test-echo-error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test-echo-upstream\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test-echo-upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ],\n \"resolver\": \"Google\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -9238,7 +11543,7 @@ } }, "url": { - "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config/{{configUid}}", + "raw": "http://{{ncg_host}}:{{ncg_port}}/{{ngc_api_version}}/config", "protocol": "http", "host": [ "{{ncg_host}}" @@ -9246,21 +11551,19 @@ "port": "{{ncg_port}}", "path": [ "{{ngc_api_version}}", - "config", - "{{configUid}}" + "config" ] } }, "response": [] } - ], - "description": "Test using:\n\n`curl -i echo.vm-test.ie.ff.lan`\n\nThe actual FQDN can be modified in the request JSON body" + ] }, { - "name": "HTTPS server", + "name": "Server-side and source of truth authentication", "item": [ { - "name": "TLS Offload", + "name": "Bearer Token, Basic and HTTP header upstream authentication", "event": [ { "listen": "test", @@ -9282,7 +11585,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ]\n }\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"Bearer token-based authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"Bearer token-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"bearer\"\n }\n },\n {\n \"name\": \"Header-based authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjAwMDEiLCJpc3MiOiJCYXNoIEpXVCBHZW5lcmF0b3IiLCJpYXQiOjE3MDI0ODEzNjcsImV4cCI6MTcwMjQ4MTM2OH0.eyJuYW1lIjoiQm9iIERldk9wcyIsInN1YiI6IkpXVCBzdWIgY2xhaW0iLCJpc3MiOiJKV1QgaXNzIGNsYWltIiwicm9sZXMiOlsiZGV2b3BzIl19.SKA_7MszAypMEtX5NDQ0TcUbVYx_Wt0hrtmuyTmrVKU\",\n \"type\": \"header\",\n \"location\": \"X-AUTH-TOKEN\"\n }\n },\n {\n \"name\": \"Basic authentication profile\",\n \"type\": \"token\",\n \"token\": {\n \"type\": \"basic\",\n \"username\": \"authusername\",\n \"password\": \"YXV0aHBhc3N3b3Jk\"\n }\n }\n ]\n }\n }\n }\n}", "options": { "raw": { "language": "json" @@ -9303,14 +11606,9 @@ } }, "response": [] - } - ] - }, - { - "name": "mTLS Client Authentication", - "item": [ + }, { - "name": "HTTPS server with mTLS, OCSP, SSL Stapling", + "name": "mTLS upstream authentication", "event": [ { "listen": "test", @@ -9332,7 +11630,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"server_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUdSRENDQkN5Z0F3SUJBZ0lVTTNJQVZIRmxhSTVsY1d0TjZxOUVhcnlka0w4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TVRBd01qTTVXaGNOCk1qUXdOakEzTVRBd01qTTVXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFMRFQ2bnZleVZlNi9VZlk2aUtHVC9oV1A0cktDSGR0ClloZWU3RGVZR29QWGhGVjB6a3grVWExanBEZ21WUE1kVEJBdnoxODg5NzlEcHBqdmNYeFhsRmpnaUhjWDhpWVgKSXovSUVMc3dKRUNITWNsNkxmelA5eDVUY1gxTEdFblFOTWhHRzA2MjlxU2NCQmQyUUNiWlY0UWE1TkxlQnQ4cQpHQ2lXY3JiQnR3YlpiSGo1dk9aenJrdHBtRFBGS1V4bXR5b2dBQnNaTllnL0F3Y1l2RXdBOEQ0QTN0VEgxcGhvCkdYY3ZvZWpJelhRMUdmYys5azR3OFhHYWFQOGd2bTdOMXN2MnU2Yld4SHRGZHpWQk9udzJyaHUvWGYyY0N0dW4KUnIxSENKQXRRSDlkbDhzZks1czBSRlVuTlVYbFBiNTFBTjBjVFVGbEYrZlVUVmVON3dNMTdmeVZVY3IydTltSwo0UGdoWjkvMml0ZUpZV3hjK3k4V2NEQzBUV3hwZ2paVEw5Tk1GK2t6SXV2TjJOWFFybjcvSU5UQTMvNFlmWGRPCloxelpTdTlkclRMcG5DZHRpOWxuRHBKODd3bW41cVZSTlZiTlZRbldEeW5yZnoyTU1DY21jLzcvdkJFN2dDemQKNFJLWHJLdHloenlQSitycmh3NmpxYVA4QytaZGRvKzkvak9QVDFTSnUxZ21VbzFuZ2hBMWh2N0M5RUYrM2xQVApYSk5WV3dtYkdWK0p4cUdKSjJSa2toMlIrZTVIREdRY2hGWjJIcXBGTGVQN0trTHJBR2RkZFZQWEZhQ0RiU0R6ClJQd0I5WFlhakg5Zm5QWEtFT3ZpVEJhQVNjWUZwTXB5cm02UkxHUGRSVnE2RUNYVlB4MDdHdGFCaEVvVWIwK2YKVkZnNExtQkx4MldQQWdNQkFBR2pnZ0VpTUlJQkhqQUpCZ05WSFJNRUFqQUFNQkVHQ1dDR1NBR0crRUlCQVFRRQpBd0lHUURBekJnbGdoa2dCaHZoQ0FRMEVKaFlrVDNCbGJsTlRUQ0JIWlc1bGNtRjBaV1FnVTJWeWRtVnlJRU5sCmNuUnBabWxqWVhSbE1CMEdBMVVkRGdRV0JCVHZFZWJGK1JDV0JhcGVPWUdpQ0YyVHZxbExYekNCaEFZRFZSMGoKQkgwd2U0QVVFdW9Db3kvcmhMQmxzcm5KdXE2QzFJczQxbFNoVGFSTE1Fa3hDekFKQmdOVkJBWVRBa2xVTVEwdwpDd1lEVlFRSURBUkJjM1JwTVJFd0R3WURWUVFLREFoVVpYTjBJRXhoWWpFWU1CWUdBMVVFQXd3UGRtMHRZbXhoCmJtc3VabVl1YkdGdWdoUld4QjhCa3lmK1RkQXc2Q3dPZE1aT0k0NlZ2REFPQmdOVkhROEJBZjhFQkFNQ0JhQXcKRXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFHUDR6ZkdseTI1RwpneTBSeC9SSTNpNzJDVlIrSXY3SW5WTUVGWDZqRHRNV3hSblFtRGZsMWtTOVF1Y3hNb0tnOE9URStMcnlzdGJsClF4WGZiakZQekNoNHB1UGtGTmNBeG1mVmR4b20xR1lodWpoYTBQOUswUURZSDZycGlUaFdSQ2greUovQm1qZ2wKTlJabks4WGRqME85Ui9XKzJrTFRac2VFbS9hZHFVQ3dkYzNBWWlNWGh4QXkvQlh3bFRQeDMyMHZCcXYxZGFyVgp5ZlVoRlM1Rkg3enV2bGtGQ1p6M3lpOGYvYXMwbkRTUkFrY3dPRFQvN1diQlN4QTk3ZzJmRk1EMEI3WlUvbndGCmU4VnRzNDl3YmZ6QWJRMk40RUc2OEVhODE1VlFRM2N6YWthdjBCdkxHL2UwT0habGxYcUVhV1ZlWFJtSWFFOHcKWko5OEhUaDJMbUlFV2Jpdm94Kyt2UXd3bVhKTm1DRFVXNnVmcHdBOVdKQ0VhYmhxeXdGVzh1dFVENzRTVXE3SApEUDhNamtJZ0o3ekl2Tkd1RkFsSzd6c2xpV2pzeUN1OGVNamhvN2pVRFhGR1R0R0ZMUGtVa08vSysrSGVVRFg0Cm1OWDJ2aHI3NGRqRkNBTTEvOTYxWnB5NUFYUzZkd2g3MFlJL2dMdldSL0J1ejBnNEp6YUI2UFo4M1ErYm9QVHYKM1ZIS2xOWjlKQlhRTmtSc3N6U0dYWG5MYmtOTmNwVFg2cnAyZ1pUSS9NNDhGTnBxanAxOXRpQVg3bWN0cTl2SgpNejhvemhEcHZmSTlnMjFsNFZlRGdpbWEwTDVBc1pQbFdIQlZjcy9yL3dMU2YzWFVYZEs0UHpCQUdIRFBidXYrCnpKOVNqS0NFVll2bHRhMHlUUVBCSFJPa2Y2MG1sVmh6Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"server_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBc05QcWU5N0pWN3I5UjlqcUlvWlArRlkvaXNvSWQyMWlGNTdzTjVnYWc5ZUVWWFRPClRINVJyV09rT0NaVTh4MU1FQy9QWHp6M3YwT21tTzl4ZkZlVVdPQ0lkeGZ5SmhjalA4Z1F1ekFrUUljeHlYb3QKL00vM0hsTnhmVXNZU2RBMHlFWWJUcmIycEp3RUYzWkFKdGxYaEJyazB0NEczeW9ZS0paeXRzRzNCdGxzZVBtOAo1bk91UzJtWU04VXBUR2EzS2lBQUd4azFpRDhEQnhpOFRBRHdQZ0RlMU1mV21HZ1pkeStoNk1qTmREVVo5ejcyClRqRHhjWnBvL3lDK2JzM1d5L2E3cHRiRWUwVjNOVUU2ZkRhdUc3OWQvWndLMjZkR3ZVY0lrQzFBZjEyWHl4OHIKbXpSRVZTYzFSZVU5dm5VQTNSeE5RV1VYNTlSTlY0M3ZBelh0L0pWUnl2YTcyWXJnK0NGbjMvYUsxNGxoYkZ6NwpMeFp3TUxSTmJHbUNObE12MDB3WDZUTWk2ODNZMWRDdWZ2OGcxTURmL2hoOWQwNW5YTmxLNzEydE11bWNKMjJMCjJXY09rbnp2Q2FmbXBWRTFWczFWQ2RZUEtldC9QWXd3Snlaei92KzhFVHVBTE4zaEVwZXNxM0tIUEk4bjZ1dUgKRHFPcG8vd0w1bDEyajczK000OVBWSW03V0NaU2pXZUNFRFdHL3NMMFFYN2VVOU5jazFWYkNac1pYNG5Hb1lrbgpaR1NTSFpINTdrY01aQnlFVm5ZZXFrVXQ0L3NxUXVzQVoxMTFVOWNWb0lOdElQTkUvQUgxZGhxTWYxK2M5Y29RCjYrSk1Gb0JKeGdXa3luS3VicEVzWTkxRldyb1FKZFUvSFRzYTFvR0VTaFJ2VDU5VVdEZ3VZRXZIWlk4Q0F3RUEKQVFLQ0FnQVBUR1pQRFRsU004VlIvL3hSdkZrUzNUTm1LSkNPOUpHMkJYUGVZM1IzejUrTlhTdTBCb0craEk1aQpwVDVZUWtLZ2ErSi9GT0ZDVlBJRzdVQmVSNTE0Q3dVRGVMamtmci8zOXJFcjRNQmlMTkFyNUR3eVVUUEtGZUlOCnV2K0E4MWg5czBNTmpsck1ad3NibElsOFV2VjFZblpGb0J2c0Z0SThRTGZ3QTlaMzZ6dXRRNzRLR2h3TVBqaUMKMGgzK2xDeG9vcGdmd0JDWGx3d0dBeWZYVTRWMWQ5SFBpdktRQVFHakJDWDM0OWVTcEQxNDNLT21wQ2xmY01LQQp3QzU1bTZsbndCTUFIamlsaVo4RXBuNE8zUlEzSmxsVlpiaXl4RWdrZkE3TG1uNm9Ca3Jwc2VxdDVObThuRVhKCnBFbXhQcUl5Znc1WUNBMEhhNkM5WUhRN1RPRW9BbHBmWld4azAxSnpoVi9aK3FmVHM1YlMwQWNaTzFOVDRaeDgKWlF2eHQ0TDJINVcrK2R6RjhReTlidzQ2M3lKb1dydWxtNy9uQ3YvL1FpNGl0eHRnYyt0N2lwVXZzaUdTVktVWQpPelhCSXNWTUlnd0F6eUtTSEhPL21rMkEwVkgxaHB3emY2L0RzR2wxSjM4TU9pVGo4dEx1RWt3cFY4WGh5MnZwCkd0cXpsT21DS1hodlVDam9iZWlYSWJwSlIzeEM1NmliRjVadk0vQUdONzI5K0xKRFNwbHJtWVJRVHh1UTJWSE8KQWFXQ01SQWFBdUtCVnBxYTRjd25WRy9POEpkN2ZPSi9tMFlIN3FpRlJHREdvdVNOdHZJUUVtaXVkK3dRWjJ6dwpUcmFNVWk0SENtNEFPa0ZNVXBsRmt1ajA2ZHRqM2RIWUtPQkdMK25vaUp4WmJxb3kwUUtDQVFFQTFiZUl6WHh6CnRFRlp2OGRlOXljOWdCUUtNNUNIbHp6NUNMZXVkTitvemxxeDNCMW1PRStxbFkyaEd3RklIWVBJajFLYS83RlkKbExmNFpiUEJRMFhiNUo5VzQzSGIyTnEydXdRQ3ZiSXhVMW9zaGJVWlhZc2FUaE15azc2VzQ5YjU3UC9HdFE3NwpTbkVZTXNrTzRUQndyS3lBdVhDVHRtTk1Qa2J1NFBxT05PeVFQY3o3Yi92VEU1eERjMENMVS9oUXM3NWFHeCs1Citld2VjeEZNa0JKTVo2c2N5TzcySEdSNHZwTHduRXUvcU5uN2JmUElSaUx1T3BwTTdHNlUwQlBPL2todHJ5ZmQKV3U3MHJYZGJSdGRJUHlsQWxSOG9zczJqWWsrRHNPUnNESm9pbkk5WU1Va3dmdHdCNTRQbytGRGtGOHBzV202RQpSaklpenFBK0piWDlTd0tDQVFFQTA4Ly9oM0NabDg2M2xUZHNrU1JKRUZKc0RtdkZkUStzMWtlNUFwMjdnWTBXCmZJbEFGZFlRR3RORUVlTk9xS3EwdTFtS0lqWHFacWNTdU9DNzZIYTE5Tk9waHVoK1dwV0t2Ni9BTWtQSjE5SUIKQ3RqS0lkc2s0U2M3WG02MnNOV1pnQm5XT1Z3QVdzU0VzTHRac1NvWUJUVTJJS1pBOVJOWHhkSEQreGZ2SWJkNApZYngzTzk4WklNQzNlVFFiOW9jVHZab0RNWGdLaHRtTy9iMnlSeEVDSGpGRmxzYlhhc1RPeG5XOWZSVXJtdGVqCk9pdVlXaEZOM2R6dmpuVEdLY0xieWY0MWpHaUVUeFViUHVpei9ZMmk5NldCNVN6MW9zaGorRU1OaFhtRzZSYXUKQUIvelhwNldtSUJ2bDNpU0lzOGJRNkh3Qm1DTjc1R2VVVG1GUUlyaVRRS0NBUUVBbTkzWVN5MXA0VndNRGI5bApObElMRzM4Q0ZhdGlDRjR5cmpYd2FWSzVkWTVWeTFneHRmMzhSa2hkNkNrZUpGQjVsSFhGajVnVEo1dW84TnVSCnB2T3JOT2swNEhxb3dWWjZFSmtUT3JCY0l4TlFCMUFXS05BTHBrZUFDcHJreDFTQlFHVW0wZVFVUjYyRjNYd2YKZXdMdUdqRlJURzJiZlZpY1FZdFFLd3J4YmczZUFRU2ZtSU9MNVBDQmpPdlU4YS9YZzgvZlBZcjlBeFkrK3VMeAorTjB2bGlnSXZVN3lkYkNkRXpodGZVQU5qeU16cVhRemExdU1iWGNkaFEzOVFHaEIvZGhyRG1TL250Tko1YjEzCjk0bUpLbTkycDR0ckRrVEYxU3h5dWk5TjBqOFQ0U1QyU0RPOXg3ZkROOHRQdk5LYUYvUE01SU5YdXk1VGptajIKQ21EWlV3S0NBUUFOUVJYSFh1ZHRsWFR0ZEhOcHZiQ0l3ZStiRTJsZXd1VlkzMUlYZE5GWDhRRTROOHAzMDFaYwpwMTI2Rk5SR1A3QmhqTi9VOWpTOXliU2xOd0xyTUFxQTBJSHFQRUF6NE9tMnh3T3E0WTBPNFVoSmFubHpsdWYrCjR0cVhOU3hmY201UmtzeFIrSXpaSVRVQWJpalZxa0dvaWNUaVZDVDZjUVJzRDQxSStCMXhxYTV4eHo1YTA4SVoKeDVWemt5d3d5QkVYS3owSjZtNFdOQ1Q3Z2RSWEdCeGUwVXgrZStEZEFJWEQ2M2c1RElzVy9HbHRhVzcySytFSQpnaHZIZVUweExjMWRIWGd5V2hQMWN1ZXFqeHM4UVpHeUYzeENZQWJhOGRrM250S0l5S3NGaVBMSWRUZGdjMklQCkZ2SmtzeG5KN2RYUjdKODlkdXRLMDN6cHJrVEZYaXQ5QW9JQkFDcjhkb2ZCcFlFL1JuTlFwbVNET29DRm1sdTkKQlozN3h5K0puZ2FrQ2RSdHFyR1lDdkZMSnI2QnpGdXE0SHpsM0piTkRCM1BkYSs4Z2VNd2cxU1htTEhrRVFrTQpXV2ptNHpmU3hiTUtKamx3REdoeUlwSU9nQ2FQL1hyT2hxTGl4bnJ6UHFHZmM4R0FZTDE2Rm1PeGVqbVk5aERtCmNibkFqZlNwUjF1WEt2S2d6d1NLQ0VWdzc0VjJSRmRqQXBLVDl3bkpOQTZiWHQ5SXFkaS96d3BYbDQ0OVczdVMKNjRjVVpaK3luYnQ5QUlxbFNjMDdNRHl1TUtueExMbDFLeEJYenNxZlVsYWtlRGVoVmdGS05OOTNXQWJJc09ieAp1d1hTd0hXa1B6RGFHeE9wdzlSMHo2S2t2N25YZnBIYW1RWENBZEdsRjkyc1QwYW80Y3FuejFJSmJ2bz0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"cacert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZjekNDQTF1Z0F3SUJBZ0lVVnNRZkFaTW4vazNRTU9nc0RuVEdUaU9PbGJ3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1NURUxNQWtHQTFVRUJoTUNTVlF4RFRBTEJnTlZCQWdNQkVGemRHa3hFVEFQQmdOVkJBb01DRlJsYzNRZwpUR0ZpTVJnd0ZnWURWUVFEREE5MmJTMWliR0Z1YXk1bVppNXNZVzR3SGhjTk1qTXdOakE0TURrMU5EQTRXaGNOCk1qUXdOakEzTURrMU5EQTRXakJKTVFzd0NRWURWUVFHRXdKSlZERU5NQXNHQTFVRUNBd0VRWE4wYVRFUk1BOEcKQTFVRUNnd0lWR1Z6ZENCTVlXSXhHREFXQmdOVkJBTU1EM1p0TFdKc1lXNXJMbVptTG14aGJqQ0NBaUl3RFFZSgpLb1pJaHZjTkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFLMlQwWXpkcjB0dWQzaVJRNGNzaGNhRVJTRzVjTDE2CkhRblhoYWw4emlUL1VRQUNIUGdzZDYwcWlEaldvQTJXb0lGWFFpUHkzOG1vZGtWRlR4Qmt5U2VldndOOFJiLzEKOFhaMS8yS1RnVmRDcHkvNm11WE15bXZYODJad05CVkV3QnoxUk5kbklUSk44cVh3a0d4bHozbDBib1loRkFyUQpNdmkxcW1RaHpDa2Zpb041MVkrYlBXOXpTQlFQdXNrcXJYYzRqTTJ0VENNQ2pTcFlvd1hXM1ppRmc5WEJ1Z09aCjFmdWd1Zmw4K1FJYzNZSEFoL1Z1NloraXFEOGxQeGRKODlBeDZaazVtOGdkVG9JdUhBbUNWaHFpUXBGRjkzSTgKbkYrSnRuYnBaNTRJUTZBbWYrYiswakMxdmY4Kzg0WUppaEVzWExyaGMxZTRTZ2dwdzEvcWpDb21QblhGVjEzUwpsUG5kVlhVR0taa1ZKdXdZTjJyZElmd3YrdCs5MGhwUVBmNmFBTjRCamRxOXdkdkQzSXVnS2JYZG5CQ0FUTEY4ClYyRTFTSE9VZGdRY3duK1d1WDVVOGdPa3B2b2VFN0g1REJ6Rks1WTZ2SHZlaTRlNkp3RTRDK3FJL1BmbTgreTEKNEpsOFBSOW5JQmdGQ3hrZWpwa2tRQ0I5U0dvMVZidzZhWmdZd0VQNHh6YXFYYXV3L3F4c0oxNUkrRTBndEs1OApuWUtkM0hqelk5Slh6V0NVNTdXbmc2SzNvTTIzNXpyRzJnNm1FaHQ4SStDckVMUFNuZURjZU8zVlJkc2dlblBCCis4U1JxVU8vWG9LWHNEU3I5amoxdWluVzYwTG5MZ0Zmc3JQeGlQVlZlMFh1TFZESlhCSlNoRDZDeGRyMnBSOGQKS25SRDZrTFpZZEtMQWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqVwpWREFmQmdOVkhTTUVHREFXZ0JRUzZnS2pMK3VFc0dXeXVjbTZyb0xVaXpqV1ZEQVBCZ05WSFJNQkFmOEVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUJad3B4Z2Z4N2thZFhvRHNyT1hUVXJ6dEFPMkFQRVJNaTAKaTkyNk9DTGFPbVVYZW1uKytXSUU1K2tUSE0wcS8vbUZCTURzSmdZSFVLUlNvRGNsNmh4TnVFNUNzS2trRVFTSgpMTHZrWlB0S2J5NGlxMitLZ1JtdVZxbXJNVTBYQzZMZDl3WmttL2huUjNtT3V6bko4MGZmV1JDQ0xGWDEwY2EzCnc5TGM1d1JLTFBZZXQvcEs5SitOYWN3TFJRYTczVFovMUpQNW9BU3czVjNoYkxlLy9UeWpnOURqUlZGY3FYWnEKWWs2Mm5qSkhZVzh3WmlhZzc0QXU4dHE5OG5KandBV1ROMFV5L2w1Q2VpWnV5bzZlU0RHVDNJNm1BdGU1VXBvWAppNXBkYlZ6VDdOZC9IOEwwZHZNdVZ2N0FmakZlcU91cUZNNkkzTnlvbStLWENxNmJQdGxBWEkzeVFZc0t4ZlRkCkw3SnRaTmx6MGJ6eHJhcHI4RmpYcjhML1ZkeHQza00xMnJwb2kzL3hsckR6Q2Q2b2YrQ1MxelBocUdpOUhvcUoKZEU5VGhYMklTdkd2akVSYzVVNFRsNjJBNHNyeGJQbUt0eWx3dGNGVEJacUJiRGY3ZjBBc2cveWhndXdTcktsQQpBNkRWVXVCRFErdGpwZ0N0b0ZlOEhLVDJ6UFVlaEQ2ZjVNQkhmU2ZUZ1crTlhFSXNvVDNsampjY1hsYXhPcFJWCkNQNWxCczNmekxyYnBxbUlLaWZhdWlTNWM4TzlSUjhjQTVzeWlBOTBmbmJIdDlmdGxpRG9jcFRzNUtrbjk2NkIKZUxMM1dXVldCYUtvanJzY1RkVXJoalNnVVBmam5FTXpnVzR2eEc3d3BVNHR2ME4yaEtHUWc0bVhhcDV0SU5Pcwp4WktnZXRHUldnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"vm-blank.ff.lan\"\n ],\n \"resolver\": \"private DNS\",\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"server_cert\",\n \"key\": \"server_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ],\n \"authentication\": {\n \"client\": [\n {\n \"profile\": \"mTLS-client-profile\"\n }\n ]\n }\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/vm-blank.ff.lan_access_log\",\n \"error\": \"/var/log/nginx/vm-blank.ff.lan_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://origin_server\"\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"origin_server\",\n \"origin\": [\n {\n \"server\": \"192.168.1.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"client\": [\n {\n \"name\": \"mTLS-client-profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"enabled\": \"on\",\n \"client_certificates\": \"cacert\",\n \"trusted_ca_certificates\": \"cacert\",\n \"ocsp\": {\n \"enabled\": \"on\",\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n },\n \"stapling\": {\n \"enabled\": true,\n \"verify\": true,\n \"responder\": \"http://ocsp.k8s.ie.ff.lan\"\n }\n }\n }\n ]\n }\n },\n \"resolvers\": [\n {\n \"name\": \"private DNS\",\n \"address\": \"192.168.2.13\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ],\n \"certificates\": [\n {\n \"type\": \"certificate\",\n \"name\": \"test_cert\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.crt\",\n \"authentication\": [\n {\n \"profile\": \"Basic authentication profile\"\n }\n ]\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"test_key\",\n \"contents\": {\n \"content\": \"{{github_gitops_root}}/{{ngc_api_version}}/testcert.key\"\n }\n },\n {\n \"type\": \"certificate\",\n \"name\": \"client_cert\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZBakNDQStxZ0F3SUJBZ0lVYXZ1aFhBOWFLVFJlYmZ2Y1BFU2Z0MjBUQXhzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1ZqRUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlZCQWdNQkVOdmNtc3hEVEFMQmdOVkJBY01CRU52Y21zeApFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUll3RkFZRFZRUUREQTEwWlhOMExtRmpiV1F1YkdGdU1CNFhEVEkwCk1EUXhOVEUzTURnMU0xb1hEVEkxTURReE5URTNNRGcxTTFvd1dERUxNQWtHQTFVRUJoTUNTVVV4RFRBTEJnTlYKQkFnTUJFTnZjbXN4RFRBTEJnTlZCQWNNQkVOdmNtc3hFVEFQQmdOVkJBb01DRUZqYldVZ1RIUmtNUmd3RmdZRApWUVFEREE5amJHbGxiblF1WVdOdFpTNXNZV0l3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLCkFvSUNBUURUQ2kydi8rc08rdTJTcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkQKUWkvL0dIZXhYS3NaelBURDUyN0ZMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOApPa3lxVFdma0xkRnF2akFGclU5czMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2CmpsV1E5NTVWUzlmZlNLU3hpQTRCQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUMKRjYrRGZmQ2FNLzVockljRkswSVFheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNOAo5UlhxQmlaNnFWdGFPQXFEK0pRVGNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4CnZvczA4TSsvOUlhWTdQeGtQNXB6bDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0QKbTlURDJKT0hTU3VmdkRkRnV1YjFwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwegpkZ1RsMDVVWjZtMFpFNUdlK1FRaG5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BCmFLZ0hTbTJROE9MS1lJdlhVN1RpME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzQKc3I0UXJ4Q2xuY2pwbUMrdkRmdHJuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJvNEhGTUlIQwpNQWtHQTFVZEV3UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ1dnTURNR0NXQ0dTQUdHK0VJQkRRUW1GaVJQCmNHVnVVMU5NSUVkbGJtVnlZWFJsWkNCRGJHbGxiblFnUTJWeWRHbG1hV05oZEdVd0hRWURWUjBPQkJZRUZGQmIKdmltZDYxekxLdlA0U2RZRFRWbndYdFVwTUI4R0ExVWRJd1FZTUJhQUZLY29GRHpMVnc1QXBiMzB5UTM0c25MZQpHQ1FWTUE0R0ExVWREd0VCL3dRRUF3SUY0REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVICkF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSmg0cm9kZEVGemJwWk5kSW5zUmdubWVnWVIxSWlzUUxRU0IKcmNydEZxVmtLb3Rsc09EUXBFMThIRjBsbVA4WE9IU0hqYytYUVF5YlFNd1ViZ2RNbnhBZE1WaGFaMXppWElnaQpiUHgwOEY0YXR5MElJY1hyOVpFVnZTd1pheURBZHErb2s5RGpoRjQwYU5iQmFBTXB2NTRCL2U3OUNMSWZ6REo4CnNZaWw3K09abWlOUTJtZUNreVBYdXdhd3hTeVRnNVhWS3Q4VEtKQVJ5aTFJeWRHWkZRMTJGWFJHTE1BSjdaYngKRzlPd1ZvazExenpWNkRQZHFuZU5ER3BQRU5WZ2VmVjI0ZU1JVXUrYzhnSThYTU1GMU9VVWR3MmlEQmU4Q01TQQppc2h2aDFWYVZPNC96czlma2dLV2FXejNwQWprN3pkbWdaUnpXRUVHR0JMekJoQk5FQTg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"\n }\n },\n {\n \"type\": \"key\",\n \"name\": \"client_key\",\n \"contents\": {\n \"content\": \"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRRFRDaTJ2LytzTyt1MlMKcFF5ZVBLM3hnb3RyRUlDZGJYMmN4N0xkcnRDbE82a0xTM3IybWpxV1ptWkRRaS8vR0hleFhLc1p6UFRENTI3RgpMZlREcExIb2h1MldmeUErQy9HN2JycXlNT0dQZ3lVcEI2NWN2THU4V1BNOE9reXFUV2ZrTGRGcXZqQUZyVTlzCjMxUnljT3BQSlB0cFloRWlhQXZRWDlwRnhjalM2NUJscUFCMjY1YnlncGs2amxXUTk1NVZTOWZmU0tTeGlBNEIKQXAzMHV3Rm5YRWtMcGRCenI1TkFKeXJqdXhzbHJGVEs4SGxvRmQ2MndzQUNGNitEZmZDYU0vNWhySWNGSzBJUQpheHBpaWUyWllKaVFmNXJMeVd6VG1xMVh1QmsyaEhBWDNvQUY2bW9hcnVNODlSWHFCaVo2cVZ0YU9BcUQrSlFUCmNpYmVzekQ2Z2xoSitGM0VFTEJOWVhETmFLbGprQXRxVWFwYStXZEdVUkU4dm9zMDhNKy85SWFZN1B4a1A1cHoKbDhmaS9RaS9ESW9WLzh0UUlydFBIYzJqSTFSRkZoL3BpeDFsR2lyTlRBK0RtOVREMkpPSFNTdWZ2RGRGdXViMQpwMnF5TW5Nd3FFNklHOGpmTEg2TGNxRGFSbmcveVpVUTBqa01LSFYrd1gwemRnVGwwNVVaNm0wWkU1R2UrUVFoCm5nY0FUemdrSWp3WlJod1JLOEx1Nmtwb2Vnb0dMUkhkTVNqcUV0NkNWc25BYUtnSFNtMlE4T0xLWUl2WFU3VGkKME9DNm5OdU40RDlKdkxGQXdPMUVFU2tCUXFQeThGby8zRVNZWU1FazJ6RzRzcjRRcnhDbG5janBtQyt2RGZ0cgpuR055SVJvditOeS9zd2FSdkcvcm15ZnhEYVdNL3dJREFRQUJBb0lDQUJzWEZBK2krRmVFbW5rdE9xdHRUL1FsCk5TUlozL05WYjJuRlcyUGRqRHhKcGtUTzV2VS9qYThVd2ZmTVIrdWxCbWhSWkVmOFBweVBMc2J5USszV29iSjAKUk9JQlprVjdYd2ZDWDdEVUJDc0VtS3ZscDlvN3JVQmJqV0w1SmpJNDhYeDI3VFR0NlFMY05uVXhUZDUxanRPagpXYXFJdzNqNU1Oc0tFdDRncWlET2RhQzIvMzJaekZkTHNHNWdnRmRnUElZOUpYUXN3bHk2VnZjdzVpU0RoTnRICkcyYWxYYXdiL2s1Sk9OWTIyY3RDT0kyUnhPUGtPc3lYRkoxYTBRQStGYmxBWExKenVubE5ZNU9iOXEwWTFpa2sKSHpGeXBUcENSdmY2dzY3em00NUYvZVdkS0MzdmpnM29JK29GUS9vMTJUdjhWV3Bhc0ptSmoraUJ5aFRpOGx4YQpMempXaHNrUFZJUGJDYjFDTmIzZHNQSWVWYTVQYmRORGh2bHBQZFV4cXhKRGI4ZUFhemxSQXJVdmtaQnpkTjZtCjVwekljNGtMQnd3Wno5eGg1MzdsQ0tlZ3ZJYmdEMlQvMEM4SVFsWmFIK1M3azlWaVU2Z1RWSGNzU1RsSm52NVYKN3VCMWczVzJZRVloZFJxNlJOUXRZaUFuTktUS2ZYb3d1UUJteWRwVWRYWUljTE5GcER6eHgvRGdQSEhnU0J1dQpQZXVMZzdpemhSSndKMTQ1eW5VTlloQnROVVJaOWlRL1cwWTJOa242UWFBZDNld1pLaVg0S3lZU2k3TTF1MFJWCmFDc1BmZWJrWkRTUnRnQ2Q5N3dGSVYyTVh0UnpXNlpKUUlDWkhHTDVkYkJrNU0xQTI2NnJSYmcvTWZJSE9mdTMKRUZBVjc2aXoyVmNtSDRzblNZUHhBb0lCQVFEc0pNWElhM3ZyRXdRSkh0alRWZE9ONk9rbEExRVN4aWtjSWdSOAo3aFRWQXk3dmtORlpFVUhYczQ1TXlYQzRxTWlvUnFhZHVtOXpQWnFBQ0tQMHRWcXdDMVdOcUFrbDBQc1pZYXcrCmpKNjRDQXA4ZnJ4UDUrOVpWREtiamRWK1ZrK1lrbC9UL0Q1djNFTnZIdkVxN3ZMSE56dE9VSmFWZXNFRERQSW8KaER5SHhjRXQwTHRXTFhoNGNMSDhIQk9Kc0wxYXcxRlhNTk1qdERzazlBMTlJRFlYTHcwaWpIeC81c3hHUGcxSQpmMXRIemhpTlN5NUU5RG9pTmJxVFQvWEEyYVdCdjJ1ZlQybmw2ekticHZHNVo0VGlOUE5ESU5MaUFXOVNNQnJnCkJtaXJFVHU4MnVSa3hnaWZTM01CZ0ZFdXVtaSt2cEhwNzhGaUNOcHpZZUFwTUxjN0FvSUJBUURreVFVT29HVjEKTzZaNXJ4KzhLbVh1S3dmbXNHNmh5cmkrNEw4MzRQakVhbHdkdFhFUmphUG8vSTVhOVFoYjNnLzF5SUdiMzdLSgpPaTFCcGVRZ1owUEVQdFgyRWI0QTNCSTA5SzExWWFybnJGM2d6WS9CVWgveEZoL1YvVEVzTTloZTZ4YlhtRm9WCktvMlY1b2NlNnQzNUJuNHVLL2xkSEJKMHJnUENQdXNKVU9JMEhtUzZkdXNQcHczRFpESkZ5SEU4anptSllwcUsKMnBEMlBBMVZ5aVBBM3MwOU12TWdNSmJXajJLQVBoYk4xQXJnTERaUTFuZ0VwaVFtM3hWdmxIVkMzN0JHM0IzcApWbmtSRE9UZnF1N1BXek40aHZnMDRaNkxBdEZuYzNnMFFxRGcvcXZlS0xuclZwOUJEUlhWb0pZZkNMaVBkajZCCmFiYnFXQ0lYTnMwTkFvSUJBUURFWllrQk9UT2t2UG44UStWOVRzSldJa0hWZ0w2cTZKaEVSNTZIOE5MdW5ta28KNGI3Ylh0anQ5dTRBdXdDKzg5Ris4dE9jRnZTZVdidm5oRWdvTzdTaSthbzcyR2RUUmsyd1BHV3UxL0VoaWI1Kwo4RURhREVJcWZ6WmYzVVNVZ0dCT3VsNXN4anQvZVNlMGdYMStnYUQxUXVCV0wvd3RjaHlZMXVtSC9RTUN3TnY3CnFNQkYyaWQ1cy9Demh2NVE0K2Q0VnoyTlVKUXArN204OENWUHpieHU1N2o2NVBDZXgydFplRDQvNzN3UmFqMU4KTmh2VFNYUVlBNnVhM1VPOUVzYnQ5REFrSFQ0cjlNTHdaWlpnNXRIRCtObmhHS21MUWpvOWxyaWpYWEVyNVhkVAppSkd2cG15Qlg1VFV5TTI4R1ZrSVd5S3I5N1ZVUFp6Qm5jTjdQb01GQW9JQkFDSWRCekFESXAyMFkwSkpwb1c4CkhLN0NvODcyQjhrQUhVUDQ1d3BCOVZYME5nQUlDZkFBR3F5bTIrTWNIajcwZ1pTNGJQcjlBL1lLUXExRE94ekoKeVFUK0NaRkRXLzFzMHhvcVVhTHJDVHk2S3RWV1VWVVdGY1V3ODFaSkJvZjh3d3FFSzBmQ1k4dzhLQmh0NHovcwo3V1F3WDZncXptZmZ3N0M2TWIxSS9HckxNSzlzeU1BMDh4L0dYUHNCZWEyR0VieGg3c1paZVlteXhXS3gyWnN0CkpOK2hXU0VDODlXYzZTRGRDR2J1MngrZHVuRnFwajZ2ZS8zVmVCYUR0UUtLTkdIZ1VMeUFIY1dwS3l3cnJBVGQKeS9ZSE4wbUZkb1VNRDBQVEM3NU5MV005ZkJlUVliZ2lnblpnMkNZdStVNTlQMlVwTzd2SWVkRjZIZGdiaEJuSwpCaEVDZ2dFQkFNZmQ2Zi90RThTQlNFUnd5YW80SThuZkhTZUlMUklvM3pqRE5vWHZ6VHlwbG00a3ovYW9QeEF0CmhPYVNmZU41bFljMXFFUkRxZzRIVGRNTUkyenZPaVFuMHNGTEJFZ0UwT0VIOEZxZVZlZGgycUJucFdXWEhwTW8KREd4TnhpUnVpSDZpOEVMVWFoaU1NQkdQVi9ONjI5MDREbnUyYVVHcHlMTzZxems3SmM5VXlITC90QVNRTFIzagp6NFBhb2xTRE5rNzJSUks0VjIyZUprM2EwYVhjRU5vM1R0OUlTUTliMG5DYVVKbFJsZTA0d2QrOWUyN0FRNUNaCkVWbUtZT1JYcW9VTGNQOEcxRm1VUGhDRkU2aEI3L1hSVWpQdmJFdm5rS05Cdko2UHppT0RMdktRK3I4TzR0WkMKQi9LTDlCdjNmdUkvQlJLeU9WZVU1VnZ5MzUveUFxVT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=\"\n }\n }\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Online boutique HTTPS\",\n \"names\": [\n \"www.online-boutique.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:443\",\n \"http2\": true,\n \"tls\": {\n \"certificate\": \"test_cert\",\n \"key\": \"test_key\",\n \"ciphers\": \"DEFAULT\",\n \"protocols\": [\n \"TLSv1.2\",\n \"TLSv1.3\"\n ]\n }\n },\n \"log\": {\n \"access\": \"/var/log/nginx/online_boutique_https_access_log\",\n \"error\": \"/var/log/nginx/online_boutique_https_error_log\"\n },\n \"locations\": [\n {\n \"uri\": \"/\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://upstream_boutique\",\n \"authentication\": {\n \"server\": [\n {\n \"profile\": \"mTLS authentication profile\"\n }\n ]\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"upstream_boutique\",\n \"origin\": [\n {\n \"server\": \"192.168.2.200:80\"\n }\n ]\n }\n ],\n \"authentication\": {\n \"server\": [\n {\n \"name\": \"mTLS authentication profile\",\n \"type\": \"mtls\",\n \"mtls\": {\n \"certificate\": \"client_cert\",\n \"key\": \"client_key\"\n }\n }\n ]\n }\n }\n }\n}", "options": { "raw": { "language": "json" @@ -9357,10 +11655,10 @@ ] }, { - "name": "NGINX Javascript", + "name": "Stream server", "item": [ { - "name": "NGINX Javascript test", + "name": "Create stream server", "event": [ { "listen": "test", @@ -9382,7 +11680,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0,\n \"modules\": [\n \"ngx_http_js_module\",\n \"ngx_stream_js_module\"\n ]\n }\n },\n \"declaration\": {\n \"http\": {\n \"servers\": [\n {\n \"name\": \"Example HTTP server with Javascript\",\n \"resolver\": \"Google\",\n \"names\": [\n \"njs-test.vm-test.ie.ff.lan\"\n ],\n \"listen\": {\n \"address\": \"0.0.0.0:80\"\n },\n \"log\": {\n \"access\": \"/var/log/nginx/njs-test.nginx.lab_access_log\",\n \"error\": \"/var/log/nginx/njs-test.nginx.lab_error_log\"\n },\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$serverVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n },\n \"locations\": [\n {\n \"uri\": \"/echo\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n },\n {\n \"uri\": \"/generatecontent\",\n \"urimatch\": \"prefix\",\n \"upstream\": \"http://test_upstream\",\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_content\"\n },\n \"profile\": \"njs_set_content\",\n \"function\": \"njsSetContent\"\n }\n ],\n \"headers\": {\n \"to_server\": {\n \"set\": [\n {\n \"name\": \"X-Injected-Client-IP\",\n \"value\": \"$remote_addr\"\n },\n {\n \"name\": \"X-HTTP-Var-Set-By-Njs\",\n \"value\": \"$httpVarSetByNjs\"\n },\n {\n \"name\": \"X-Server-Var-Set-By-Njs\",\n \"value\": \"$serverVarSetByNjs\"\n },\n {\n \"name\": \"Host\",\n \"value\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n }\n }\n ]\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"test_upstream\",\n \"origin\": [\n {\n \"server\": \"echo.free.beeceptor.com\"\n }\n ]\n }\n ],\n \"njs\": [\n {\n \"hook\": {\n \"type\": \"js_set\",\n \"js_set\": {\n \"variable\": \"$httpVarSetByNjs\"\n }\n },\n \"profile\": \"njs_set_variable\",\n \"function\": \"njsSetVariable\"\n }\n ],\n \"njs_profiles\": [\n {\n \"name\": \"njs_set_variable\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0VmFyaWFibGUocikgewogICAgcmV0dXJuICJWYXJpYWJsZV9zZXRfYnlfamF2YXNjcmlwdCAtIFVSSSAiK3IudXJpOwp9CgpleHBvcnQgZGVmYXVsdCB7bmpzU2V0VmFyaWFibGV9Cgo=\"\n }\n },\n {\n \"name\": \"njs_set_content\",\n \"file\": {\n \"content\": \"ZnVuY3Rpb24gbmpzU2V0Q29udGVudChyKSB7CiAgci5yZXR1cm4oMjAwLCAiSGVsbG8gd29ybGQhXG4iKTsKfQoKZXhwb3J0IGRlZmF1bHQge25qc1NldENvbnRlbnR9Cg==\"\n }\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Google\",\n \"address\": \"8.8.8.8\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", + "raw": "{\n \"output\": {\n \"type\": \"nginxone\",\n \"nginxone\": {\n \"url\": \"{{nginxone_url}}\",\n \"namespace\": \"{{nginxone_namespace}}\",\n \"token\": \"{{nginxone_token}}\",\n \"configsyncgroup\": \"{{nginxone_configsyncgroup}}\",\n \"synctime\": 0\n }\n },\n \"declaration\": {\n \"layer4\": {\n \"servers\": [\n {\n \"name\": \"DNS Load Balancer\",\n \"resolver\": \"Quad-ones\",\n \"listen\": {\n \"address\": \"10053\",\n \"protocol\": \"udp\"\n },\n \"upstream\": \"google_DNS_upstream\"\n }\n ],\n \"upstreams\": [\n {\n \"name\": \"google_DNS_upstream\",\n \"origin\": [\n {\n \"server\": \"ns1.google.com:53\"\n },\n {\n \"server\": \"ns2.google.com:53\"\n }\n ],\n \"resolver\": \"Quad9\"\n }\n ]\n },\n \"resolvers\": [\n {\n \"name\": \"Quad9\",\n \"address\": \"9.9.9.9\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n },\n {\n \"name\": \"Quad-ones\",\n \"address\": \"1.1.1.1\",\n \"ipv4\": true,\n \"ipv6\": false,\n \"timeout\": \"30s\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json" @@ -9435,7 +11733,7 @@ "variable": [ { "key": "ncg_host", - "value": "127.0.0.1", + "value": "", "type": "default" }, { @@ -9454,7 +11752,7 @@ }, { "key": "nim_host", - "value": "https://", + "value": "https://", "type": "string" }, { @@ -9469,7 +11767,7 @@ }, { "key": "nim_instancegroup", - "value": "declarativeAPITest", + "value": "", "type": "string" }, { @@ -9484,7 +11782,7 @@ }, { "key": "ngc_api_version", - "value": "v5.1", + "value": "v5.2", "type": "string" }, { @@ -9494,7 +11792,7 @@ }, { "key": "nginxone_token", - "value": "", + "value": "", "type": "string" }, { @@ -9504,13 +11802,23 @@ }, { "key": "nginxone_configsyncgroup", - "value": "declarativeAPITest", + "value": "", "type": "string" }, { "key": "moesif_application_id", "value": "", "type": "string" + }, + { + "key": "nginx_license_token", + "value": "", + "type": "string" + }, + { + "key": "nginx_reporting_server", + "value": "product.connect.nginx.com", + "type": "string" } ] } \ No newline at end of file diff --git a/contrib/postman/README.md b/contrib/postman/README.md index 78db66f..ec6d9ba 100644 --- a/contrib/postman/README.md +++ b/contrib/postman/README.md @@ -2,9 +2,11 @@ This collection contains several declaration examples for the following Declarative API releases: +* API v5.2 - Required for NGINX Plus R33+ * API v5.1 * API v5.0 -* API v4.2 + +**Note**: NGINX Plus R33 and above [require a valid license](https://docs.nginx.com/solutions/about-subscription-licenses/) and the `.output.license` section in the declarative JSON is required. See the [usage notes](/USAGE-v5.2.md) for further details. [Postman collection](/contrib/postman) examples are provided for R33. --- diff --git a/etc/config.toml b/etc/config.toml index 4091cd0..e26b559 100644 --- a/etc/config.toml +++ b/etc/config.toml @@ -3,7 +3,7 @@ # Main variables [main] banner = "NGINX Declarative API" -version = "5.1" +version = "5.2" url = "https://github.com/f5devcentral/NGINX-Declarative-API" # Templates @@ -11,6 +11,7 @@ url = "https://github.com/f5devcentral/NGINX-Declarative-API" root_dir = "../templates" nginxmain = "nginx-conf/nginx.conf" mimetypes = "nginx-conf/mime.types" +license = "nginx-conf/license-key.tmpl" httpconf = "http.tmpl" apigwconf = "apigateway.tmpl" @@ -51,7 +52,6 @@ compiler_uri = "/v1/compile/policy" # Staged configuration directories [nms] -nginx_conf = '/etc/nginx/nginx.conf' config_dir = '/etc/nginx' certs_dir = '/etc/nginx/ssl' apigw_dir = '/etc/nginx/apigateway' diff --git a/src/V4_2_CreateConfig.py b/src/V5_2_CreateConfig.py similarity index 54% rename from src/V4_2_CreateConfig.py rename to src/V5_2_CreateConfig.py index 824c39d..da18068 100644 --- a/src/V4_2_CreateConfig.py +++ b/src/V5_2_CreateConfig.py @@ -18,31 +18,29 @@ from pydantic import ValidationError from requests.packages.urllib3.exceptions import InsecureRequestWarning -import v4_2.APIGateway -import v4_2.DevPortal -import v4_2.DeclarationPatcher -import v4_2.GitOps -import v4_2.MiscUtils +import v5_2.APIGateway +import v5_2.DevPortal +import v5_2.DeclarationPatcher +import v5_2.GitOps +import v5_2.MiscUtils +import v5_2.NMSOutput +import v5_2.NGINXOneOutput # NGINX App Protect helper functions -import v4_2.NAPUtils -import v4_2.NIMUtils +import v5_2.NAPUtils +import v5_2.NIMUtils # NGINX Declarative API modules from NcgConfig import NcgConfig from NcgRedis import NcgRedis # pydantic models -from V4_2_NginxConfigDeclaration import * +from V5_2_NginxConfigDeclaration import * # Tolerates self-signed TLS certificates requests.packages.urllib3.disable_warnings(InsecureRequestWarning) -def getuniqueid(): - return uuid.uuid4() - - def configautosync(configUid): print("Autosyncing configuid [" + configUid + "]") @@ -63,10 +61,13 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn # Building NGINX configuration for the given declaration # NGINX configuration files for staged config - configFiles = {'files': [], 'rootDir': NcgConfig.config['nms']['config_dir']} + configFiles = {'files': []} # NGINX auxiliary files for staged config - auxFiles = {'files': [], 'rootDir': NcgConfig.config['nms']['config_dir']} + auxFiles = {'files': []} + + # Extra manifests to be returned to the caller + extraOutputManifests = [] try: # Pydantic JSON validation @@ -79,11 +80,36 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn j2_env = Environment(loader=FileSystemLoader(NcgConfig.config['templates']['root_dir'] + '/' + apiversion), trim_blocks=True, extensions=["jinja2_base64_filters.Base64Filters"]) - j2_env.filters['regex_replace'] = v4_2.MiscUtils.regex_replace + j2_env.filters['regex_replace'] = v5_2.MiscUtils.regex_replace + + # Check resolver profiles validity and creates resolver config files + if 'resolvers' in d['declaration']: + all_resolver_profiles = [] + + d_resolver_profiles = v5_2.MiscUtils.getDictKey(d, 'declaration.resolvers') + if d_resolver_profiles is not None: + # Render all resolver profiles + for i in range(len(d_resolver_profiles)): + resolver_profile = d_resolver_profiles[i] + + # Add the rendered resolver configuration snippet as a config file in the staged configuration + templateName = NcgConfig.config['templates']['misc_root'] + "/resolver.tmpl" + renderedResolverProfile = j2_env.get_template(templateName).render( + resolverprofile=resolver_profile, ncgconfig=NcgConfig.config) + + b64renderedResolverProfile = base64.b64encode(bytes(renderedResolverProfile, 'utf-8')).decode( + 'utf-8') + configFileName = NcgConfig.config['nms']['resolver_dir'] + '/' + resolver_profile['name'].replace(' ', + '_') + ".conf" + resolverProfileConfigFile = {'contents': b64renderedResolverProfile, + 'name': configFileName} + + all_resolver_profiles.append(resolver_profile['name']) + auxFiles['files'].append(resolverProfileConfigFile) if 'http' in d['declaration']: if 'snippet' in d['declaration']['http']: - status, snippet = v4_2.GitOps.getObjectFromRepo(object = d['declaration']['http']['snippet'], authProfiles = d['declaration']['http']['authentication']) + status, snippet = v5_2.GitOps.getObjectFromRepo(object = d['declaration']['http']['snippet'], authProfiles = d['declaration']['http']['authentication']) if status != 200: return {"status_code": 422, "message": {"status_code": status, "message": snippet}} @@ -96,24 +122,41 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn if 'upstreams' in http: for i in range(len(http['upstreams'])): - upstream = http['upstreams'][i] + if upstream['resolver'] and upstream['resolver'] not in all_resolver_profiles: + return {"status_code": 422, + "message": {"status_code": status, "message": + {"code": status, + "content": f"invalid resolver profile [{upstream['resolver']}] in HTTP upstream [{upstream['name']}], must be one of {all_resolver_profiles}"}}} + if upstream['snippet']: - status, snippet = v4_2.GitOps.getObjectFromRepo(object = upstream['snippet'], authProfiles = d['declaration']['http']['authentication']) + status, snippet = v5_2.GitOps.getObjectFromRepo(object = upstream['snippet'], authProfiles = d['declaration']['http']['authentication']) if status != 200: return {"status_code": 422, "message": {"status_code": status, "message": snippet}} d['declaration']['http']['upstreams'][i]['snippet'] = snippet + # Add the rendered upstream configuration snippet as a config file in the staged configuration + templateName = NcgConfig.config['templates']['misc_root'] + "/upstream-http.tmpl" + renderedUpstreamProfile = j2_env.get_template(templateName).render( + u=upstream, ncgconfig=NcgConfig.config) + + b64renderedUpstreamProfile = base64.b64encode(bytes(renderedUpstreamProfile, 'utf-8')).decode( + 'utf-8') + configFileName = NcgConfig.config['nms']['upstream_http_dir'] + '/' + upstream['name'].replace(' ', '_') + ".conf" + upstreamProfileConfigFile = {'contents': b64renderedUpstreamProfile, + 'name': configFileName} + + auxFiles['files'].append(upstreamProfileConfigFile) all_upstreams.append(http['upstreams'][i]['name']) # Check HTTP rate_limit profiles validity all_ratelimits = [] http = d['declaration']['http'] - d_rate_limit = v4_2.MiscUtils.getDictKey(d, 'declaration.http.rate_limit') + d_rate_limit = v5_2.MiscUtils.getDictKey(d, 'declaration.http.rate_limit') if d_rate_limit is not None: for i in range(len(d_rate_limit)): all_ratelimits.append(d_rate_limit[i]['name']) @@ -124,7 +167,7 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn all_auth_client_profiles = [] all_auth_server_profiles = [] - d_auth_profiles = v4_2.MiscUtils.getDictKey(d, 'declaration.http.authentication') + d_auth_profiles = v5_2.MiscUtils.getDictKey(d, 'declaration.http.authentication') if d_auth_profiles is not None: if 'client' in d_auth_profiles: # Render all client authentication profiles @@ -221,7 +264,7 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn # List of all authorization client profile names all_authz_client_profiles = [] - d_authz_profiles = v4_2.MiscUtils.getDictKey(d, 'declaration.http.authorization') + d_authz_profiles = v5_2.MiscUtils.getDictKey(d, 'declaration.http.authorization') if d_authz_profiles is not None: # Render all client authorization profiles @@ -260,13 +303,13 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn # NGINX Javascript profiles all_njs_profiles = [] - d_njs_files = v4_2.MiscUtils.getDictKey(d, 'declaration.http.njs_profiles') + d_njs_files = v5_2.MiscUtils.getDictKey(d, 'declaration.http.njs_profiles') if d_njs_files is not None: for i in range(len(d_njs_files)): njs_file = d_njs_files[i] njs_filename = njs_file['name'].replace(' ','_') - status, content = v4_2.GitOps.getObjectFromRepo(object=njs_file['file'], + status, content = v5_2.GitOps.getObjectFromRepo(object=njs_file['file'], authProfiles=d['declaration']['http'][ 'authentication']) @@ -279,7 +322,7 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn all_njs_profiles.append(njs_filename) # HTTP level Javascript hooks - d_http_njs_hooks = v4_2.MiscUtils.getDictKey(d, 'declaration.http.njs') + d_http_njs_hooks = v5_2.MiscUtils.getDictKey(d, 'declaration.http.njs') if d_http_njs_hooks is not None: for i in range(len(d_http_njs_hooks)): if d_http_njs_hooks[i]['profile'] not in all_njs_profiles: @@ -289,11 +332,19 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn "content": f"invalid njs profile [{d_http_njs_hooks[i]['profile']}] in HTTP declaration, must be one of {all_njs_profiles}"}}} # Parse HTTP servers - d_servers = v4_2.MiscUtils.getDictKey(d, 'declaration.http.servers') + d_servers = v5_2.MiscUtils.getDictKey(d, 'declaration.http.servers') if d_servers is not None: for server in d_servers: serverSnippet = '' + # Server level resolver name validity check + if server['resolver']: + if server['resolver'] not in all_resolver_profiles: + return {"status_code": 422, + "message": {"status_code": status, "message": + {"code": status, + "content": f"invalid resolver profile [{server['resolver'] }] in HTTP server [{server['name']}], must be one of {all_resolver_profiles}"}}} + # Server level Javascript hooks if server['njs']: for i in range(len(server['njs'])): @@ -322,8 +373,19 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn {"code": status, "content": f"invalid client authorization profile [{server['authorization']['profile']}] in server [{server['name']}] must be one of {all_authz_client_profiles}"}}} + # mTLS client authentication name validity check + if 'authentication' in server['listen']['tls']: + if 'client' in server['listen']['tls']['authentication']: + tlsAuthProfiles = server['listen']['tls']['authentication']['client'] + for mtlsClientProfile in tlsAuthProfiles: + if mtlsClientProfile['profile'] not in all_auth_client_profiles: + return {"status_code": 422, + "message": {"status_code": status, "message": + {"code": status, + "content": f"invalid client authentication profile [{mtlsClientProfile['profile']}] in server [{server['name']}] must be one of {all_auth_client_profiles}"}}} + if server['snippet']: - status, serverSnippet = v4_2.GitOps.getObjectFromRepo(object = server['snippet'], authProfiles = d['declaration']['http']['authentication'], base64Encode = False) + status, serverSnippet = v5_2.GitOps.getObjectFromRepo(object = server['snippet'], authProfiles = d['declaration']['http']['authentication'], base64Encode = False) if status != 200: return {"status_code": 422, "message": {"status_code": status, "message": serverSnippet}} @@ -342,7 +404,7 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn "content": f"invalid njs profile [{loc['njs'][i]['profile']}] in location [{loc['uri']}], must be one of {all_njs_profiles}"}}} if loc['snippet']: - status, snippet = v4_2.GitOps.getObjectFromRepo(object = loc['snippet'], authProfiles = d['declaration']['http']['authentication']) + status, snippet = v5_2.GitOps.getObjectFromRepo(object = loc['snippet'], authProfiles = d['declaration']['http']['authentication']) if status != 200: return {"status_code": 422, "message": {"status_code": status, "message": snippet}} @@ -382,6 +444,52 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn "message": {"status_code": status, "message": {"code": status, "content": f"invalid server authentication profile [{authServerProfile['profile']}] in location [{loc['uri']}]"}}} + # API Gateway visualization integrations + apiGwVisibilityIntegrations = {} + + if loc['apigateway'] and loc['apigateway']['visibility']: + visibility_integrations = loc['apigateway']['visibility'] + for i in range(len(visibility_integrations)): + vis = visibility_integrations[i] + + if vis['enabled'] == True: + apiGwVisibilityIntegrations[ vis['type'] ] = True + + if vis['type'].lower() == 'moesif': + # Moesif integration + + # Add the rendered Moesif visibility configuration snippet as a config file in the staged configuration - HTTP context + templateName = NcgConfig.config['templates'][ + 'visibility_root'] + "/moesif/http.tmpl" + renderedMoesifHTTP = j2_env.get_template(templateName).render( + vis=vis, loc=loc, ncgconfig=NcgConfig.config) + + b64renderedMoesifHTTP = base64.b64encode( + bytes(renderedMoesifHTTP, 'utf-8')).decode( + 'utf-8') + moesifHTTPConfigFile = {'contents': b64renderedMoesifHTTP, + 'name': NcgConfig.config['nms'][ + 'visibility_dir'] + + loc['uri'] + "-moesif-http.conf"} + + auxFiles['files'].append(moesifHTTPConfigFile) + + # Add the rendered Moesif visibility configuration snippet as a config file in the staged configuration - server context + templateName = NcgConfig.config['templates'][ + 'visibility_root'] + "/moesif/server.tmpl" + renderedMoesifServer = j2_env.get_template(templateName).render( + vis=vis, loc=loc, ncgconfig=NcgConfig.config) + + b64renderedMoesifServer = base64.b64encode( + bytes(renderedMoesifServer, 'utf-8')).decode( + 'utf-8') + moesifServerConfigFile = {'contents': b64renderedMoesifServer, + 'name': NcgConfig.config['nms'][ + 'visibility_dir'] + + loc['uri'] + "-moesif-server.conf"} + + auxFiles['files'].append(moesifServerConfigFile) + # API Gateway provisioning if loc['apigateway'] and loc['apigateway']['api_gateway'] and loc['apigateway']['api_gateway']['enabled'] and loc['apigateway']['api_gateway']['enabled'] == True: openApiAuthProfile = loc['apigateway']['openapi_schema']['authentication'] @@ -391,12 +499,12 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn {"code": status, "content": f"invalid server authentication profile [{openApiAuthProfile[0]['profile']}] for OpenAPI schema [{loc['apigateway']['openapi_schema']['content']}]"}}} - status, apiGatewayConfigDeclaration = v4_2.APIGateway.createAPIGateway(locationDeclaration = loc, authProfiles = d['declaration']['http']['authentication']) + status, apiGatewayConfigDeclaration, openAPISchemaJSON = v5_2.APIGateway.createAPIGateway(locationDeclaration = loc, authProfiles = loc['apigateway']['openapi_schema']['authentication']) # API Gateway configuration template rendering if apiGatewayConfigDeclaration: apiGatewaySnippet = j2_env.get_template(NcgConfig.config['templates']['apigwconf']).render( - declaration=apiGatewayConfigDeclaration, ncgconfig=NcgConfig.config) + declaration=apiGatewayConfigDeclaration, enabledVisibility=apiGwVisibilityIntegrations, ncgconfig=NcgConfig.config) apiGatewaySnippetb64 = base64.b64encode(bytes(apiGatewaySnippet, 'utf-8')).decode('utf-8') newAuxFile = {'contents': apiGatewaySnippetb64, 'name': NcgConfig.config['nms']['apigw_dir'] + @@ -406,21 +514,33 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn # API Gateway Developer portal provisioning if loc['apigateway'] and loc['apigateway']['developer_portal'] and 'enabled' in loc['apigateway']['developer_portal'] and loc['apigateway']['developer_portal']['enabled'] == True: - status, devPortalHTML = v4_2.DevPortal.createDevPortal(locationDeclaration = loc, authProfiles = d['declaration']['http']['authentication']) + if loc['apigateway']['developer_portal']['type'].lower() == 'redocly': + ### Redocly developer portal - Add optional API Developer portal HTML files + status, devPortalHTML = v5_2.DevPortal.createDevPortal(locationDeclaration=loc, + authProfiles= + d['declaration']['http'][ + 'authentication']) - if status != 200: - return {"status_code": 412, - "message": {"status_code": status, "message": - {"code": status, "content": f"Developer Portal creation failed for {loc['uri']}"}}} + if status != 200: + return {"status_code": 412, + "message": {"status_code": status, "message": + {"code": status, + "content": f"Developer Portal creation failed for {loc['uri']}"}}} - ### Add optional API Developer portal HTML files - # devPortalHTML - newAuxFile = {'contents': devPortalHTML, 'name': NcgConfig.config['nms']['devportal_dir'] + - loc['apigateway']['developer_portal']['uri']} - auxFiles['files'].append(newAuxFile) + newAuxFile = {'contents': devPortalHTML, 'name': NcgConfig.config['nms']['devportal_dir'] + + loc['apigateway']['developer_portal']['redocly']['uri']} + auxFiles['files'].append(newAuxFile) + + ### / Redocly developer portal - Add optional API Developer portal HTML files + elif loc['apigateway']['developer_portal']['type'].lower() == 'backstage': + ### Backstage developer portal - Create Kubernetes Backstage manifest + backstageManifest = j2_env.get_template(f"{NcgConfig.config['templates']['devportal_root']}/backstage.tmpl").render( + declaration=loc['apigateway']['developer_portal']['backstage'], openAPISchema = v5_2.MiscUtils.json_to_yaml(openAPISchemaJSON), ncgconfig=NcgConfig.config) - ### / Add optional API Developer portal HTML files + extraOutputManifests.append(backstageManifest) + ### / Backstage developer portal - Create Kubernetes Backstage manifest + # Check rate limit profile name validity if loc['rate_limit'] is not None: if 'profile' in loc['rate_limit'] and loc['rate_limit']['profile'] and loc['rate_limit'][ 'profile'] not in all_ratelimits: @@ -438,17 +558,54 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn # Check Layer4/stream upstreams validity all_upstreams = [] - d_upstreams = v4_2.MiscUtils.getDictKey(d, 'declaration.layer4.upstreams') + d_upstreams = v5_2.MiscUtils.getDictKey(d, 'declaration.layer4.upstreams') if d_upstreams is not None: for i in range(len(d_upstreams)): + upstream = d_upstreams[i] + + if upstream['resolver'] and upstream['resolver'] not in all_resolver_profiles: + return {"status_code": 422, + "message": {"status_code": status, "message": + {"code": status, + "content": f"invalid resolver profile [{upstream['resolver']}] in stream upstream [{upstream['name']}], must be one of {all_resolver_profiles}"}}} + + if upstream['snippet']: + status, snippet = v5_2.GitOps.getObjectFromRepo(object = upstream['snippet'], authProfiles = d['declaration']['http']['authentication']) + + if status != 200: + return {"status_code": 422, "message": {"status_code": status, "message": snippet}} + + d['declaration']['layer4']['upstreams'][i]['snippet'] = snippet + + # Add the rendered upstream configuration snippet as a config file in the staged configuration + templateName = NcgConfig.config['templates']['misc_root'] + "/upstream-stream.tmpl" + renderedUpstreamProfile = j2_env.get_template(templateName).render( + u=upstream, ncgconfig=NcgConfig.config) + + b64renderedUpstreamProfile = base64.b64encode(bytes(renderedUpstreamProfile, 'utf-8')).decode( + 'utf-8') + configFileName = NcgConfig.config['nms']['upstream_stream_dir'] + '/' + upstream['name'].replace(' ', '_') + ".conf" + upstreamProfileConfigFile = {'contents': b64renderedUpstreamProfile, + 'name': configFileName} + + auxFiles['files'].append(upstreamProfileConfigFile) + all_upstreams.append(d_upstreams[i]['name']) - d_servers = v4_2.MiscUtils.getDictKey(d, 'declaration.layer4.servers') + d_servers = v5_2.MiscUtils.getDictKey(d, 'declaration.layer4.servers') if d_servers is not None: for server in d_servers: + # Server level resolver name validity check + if server['resolver']: + if server['resolver'] not in all_resolver_profiles: + return {"status_code": 422, + "message": {"status_code": status, "message": + {"code": status, + "content": f"invalid resolver profile [{server['resolver'] }] in stream server [{server['name']}], must be one of {all_resolver_profiles}"}}} + if server['snippet']: - status, snippet = v4_2.GitOps.getObjectFromRepo(object = server['snippet'], authProfiles = d['declaration']['http']['authentication']) + status, snippet = v5_2.GitOps.getObjectFromRepo(object = server['snippet'], authProfiles = d['declaration']['http']['authentication']) if status != 200: return {"status_code": 422, "message": {"status_code": status, "message": snippet}} @@ -473,377 +630,45 @@ def createconfig(declaration: ConfigDeclaration, apiversion: str, runfromautosyn b64HttpConf = str(base64.b64encode(httpConf.encode("utf-8")), "utf-8") b64StreamConf = str(base64.b64encode(streamConf.encode("utf-8")), "utf-8") - if decltype.lower() == "plaintext": - # Plaintext output - return httpConf + streamConf - - elif decltype.lower() == "json" or decltype.lower() == 'http': - # JSON-wrapped b64-encoded output - payload = {"http_config": f"{b64HttpConf}", "stream_config": f"{b64StreamConf}"} - - if decltype.lower() == "json": - # JSON output - return {"status_code": 200, "message": {"status_code": 200, "message": payload}} - else: - # HTTP POST output - try: - r = requests.post(d['output']['http']['url'], data=json.dumps(payload), - headers={'Content-Type': 'application/json'}) - except: - headers = {'Content-Type': 'application/json'} - content = {'message': d['output']['http']['url'] + ' unreachable'} - - return {"status_code": 502, "message": {"status_code": 502, "message": content}, "headers": headers} - - r.headers.pop("Content-Length") if "Content-Length" in r.headers else '' - r.headers.pop("Server") if "Server" in r.headers else '' - r.headers.pop("Date") if "Date" in r.headers else '' - r.headers.pop("Content-Type") if "Content-Type" in r.headers else '' - - r.headers['Content-Type'] = 'application/json' - - return {"status_code": r.status_code, "message": {"code": r.status_code, "content": r.text}, - "headers": r.headers} - - elif decltype.lower() == 'configmap': - # Kubernetes ConfigMap output - cmHttp = j2_env.get_template(NcgConfig.config['templates']['configmap']).render(nginxconfig=httpConf, - name=d['output']['configmap'][ - 'name'] + '.http', - filename= - d['output']['configmap'][ - 'filename'] + '.http', - namespace= - d['output']['configmap'][ - 'namespace']) - cmStream = j2_env.get_template(NcgConfig.config['templates']['configmap']).render(nginxconfig=streamConf, - name=d['output']['configmap'][ - 'name'] + '.stream', - filename= - d['output']['configmap'][ - 'filename'] + '.stream', - namespace= - d['output']['configmap'][ - 'namespace']) - - return Response(content=cmHttp + '\n---\n' + cmStream, headers={'Content-Type': 'application/x-yaml'}) - - elif decltype.lower() == 'nms': - # NGINX Instance Manager Staged Configuration publish - - nmsUsername = v4_2.MiscUtils.getDictKey(d, 'output.nms.username') - nmsPassword = v4_2.MiscUtils.getDictKey(d, 'output.nms.password') - nmsInstanceGroup = v4_2.MiscUtils.getDictKey(d, 'output.nms.instancegroup') - nmsSynctime = v4_2.MiscUtils.getDictKey(d, 'output.nms.synctime') - - nmsUrlFromJson = v4_2.MiscUtils.getDictKey(d, 'output.nms.url') - urlCheck = urlparse(nmsUrlFromJson) - - if urlCheck.scheme not in ['http', 'https'] or urlCheck.scheme == "" or urlCheck.netloc == "": - return {"status_code": 400, - "message": {"status_code": 400, "message": {"code": 400, - "content": f"invalid NGINX Management Suite URL {nmsUrlFromJson}"}}, - "headers": {'Content-Type': 'application/json'}} - - nmsUrl = f"{urlCheck.scheme}://{urlCheck.netloc}" - - if nmsSynctime < 0: - return {"status_code": 400, - "message": {"status_code": 400, "message": {"code": 400, "content": "synctime must be >= 0"}}, - "headers": {'Content-Type': 'application/json'}} - - # Fetch NGINX App Protect WAF policies from source of truth if needed - d_policies = v4_2.MiscUtils.getDictKey(d, 'output.nms.policies') - if d_policies is not None: - for policy in d_policies: - if 'versions' in policy: - for policyVersion in policy['versions']: - status, content = v4_2.GitOps.getObjectFromRepo(object = policyVersion['contents'], authProfiles = d['declaration']['http']['authentication']) + if decltype.lower() == 'nms': + # Output to NGINX Instance Manager - if status != 200: - return {"status_code": 422, "message": {"status_code": status, "message": content}} + # NGINX configuration files for staged config + configFiles['rootDir'] = NcgConfig.config['nms']['config_dir'] - policyVersion['contents'] = content + # NGINX auxiliary files for staged config + auxFiles['rootDir'] = NcgConfig.config['nms']['config_dir'] - # Check TLS items validity - all_tls = {'certificate': {}, 'key': {}} + finalReply = v5_2.NMSOutput.NMSOutput(d = d, declaration = declaration, apiversion = apiversion, + b64HttpConf = b64HttpConf, b64StreamConf = b64StreamConf, + configFiles = configFiles, + auxFiles = auxFiles, + runfromautosync = runfromautosync, configUid = configUid ) - d_certs = v4_2.MiscUtils.getDictKey(d, 'output.nms.certificates') - if d_certs is not None: - for i in range(len(d_certs)): - if d_certs[i]['name']: - all_tls[d_certs[i]['type']][d_certs[i]['name']] = True + if finalReply['status_code'] == 200: + finalReply['message']['message']['content']['manifests'] = extraOutputManifests - d_servers = v4_2.MiscUtils.getDictKey(d, 'declaration.http.servers') - if d_servers is not None: - for server in d_servers: - if server['listen'] is not None: - if 'tls' in server['listen']: - cert_name = v4_2.MiscUtils.getDictKey(server, 'listen.tls.certificate') - if cert_name and cert_name not in all_tls['certificate']: - return {"status_code": 422, - "message": { - "status_code": 422, - "message": {"code": 422, - "content": "invalid TLS certificate " + - cert_name + " for server" + str( - server['names'])} - }} - - cert_key = v4_2.MiscUtils.getDictKey(server, 'listen.tls.key') - if cert_key and cert_key not in all_tls['key']: - return {"status_code": 422, - "message": { - "status_code": 422, - "message": {"code": 422, - "content": "invalid TLS key " + cert_key + " for server" + str( - server['names'])} - }} - - trusted_cert_name = v4_2.MiscUtils.getDictKey(server, 'listen.tls.trusted_ca_certificates') - if trusted_cert_name and trusted_cert_name not in all_tls['certificate']: - return {"status_code": 422, - "message": { - "status_code": 422, - "message": {"code": 422, - "content": "invalid trusted CA certificate " + - trusted_cert_name + " for server" + str(server['names'])} - }} - - if v4_2.MiscUtils.getDictKey(server, 'listen.tls.mtls.enabled') in ['optional_no_ca'] \ - and 'ocsp' in server['listen']['tls']: - return {"status_code": 422, - "message": { - "status_code": 422, - "message": {"code": 422, - "content": "OCSP is incompatible with 'optional_no_ca' client " - "mTLS verification for server" + str( - server['names'])} - }} - - client_cert_name = v4_2.MiscUtils.getDictKey(server, 'listen.tls.mtls.client_certificates') - if client_cert_name and client_cert_name not in all_tls['certificate']: - return {"status_code": 422, - "message": { - "status_code": 422, - "message": {"code": 422, - "content": f"invalid mTLS client certificates [{client_cert_name}] for server {str(server['names'])}"} - }} + return finalReply - # Add optional certificates specified under output.nms.certificates - extensions_map = {'certificate': '.crt', 'key': '.key'} + elif decltype.lower() == 'nginxone': + # Output to NGINX One Cloud Console - d_certificates = v4_2.MiscUtils.getDictKey(d, 'output.nms.certificates') - if d_certificates is not None: - for c in d_certificates: - status, certContent = v4_2.GitOps.getObjectFromRepo(object = c['contents'], authProfiles = d['declaration']['http']['authentication']) + # NGINX configuration files for staged config + configFiles['name'] = NcgConfig.config['nms']['config_dir'] - if status != 200: - return {"status_code": 422, - "message": {"status_code": status, "message": {"code": status, "content": certContent}}} - - newAuxFile = {'contents': certContent['content'], 'name': NcgConfig.config['nms']['certs_dir'] + - '/' + c['name'] + extensions_map[c['type']]} - auxFiles['files'].append(newAuxFile) - - ### / Add optional certificates specified under output.nms.certificates - - # NGINX main configuration file through template - j2_env = Environment(loader=FileSystemLoader(NcgConfig.config['templates']['root_dir'] + '/' + apiversion), - trim_blocks=True, extensions=["jinja2_base64_filters.Base64Filters"]) - - nginxMainConf = j2_env.get_template(NcgConfig.config['templates']['nginxmain']).render( - nginxconf={'modules': v4_2.MiscUtils.getDictKey(d, 'output.nms.modules')}) - - # Base64-encoded NGINX main configuration (/etc/nginx/nginx.conf) - b64NginxMain = str(base64.urlsafe_b64encode(nginxMainConf.encode("utf-8")), "utf-8") - - # Base64-encoded NGINX mime.types (/etc/nginx/mime.types) - f = open(NcgConfig.config['templates']['root_dir'] + '/' + apiversion + '/' + NcgConfig.config['templates'][ - 'mimetypes'], 'r') - nginxMimeTypes = f.read() - f.close() - - b64NginxMimeTypes = str(base64.urlsafe_b64encode(nginxMimeTypes.encode("utf-8")), "utf-8") - filesMimeType = {'contents': b64NginxMimeTypes, 'name': NcgConfig.config['nms']['config_dir'] + '/mime.types'} - auxFiles['files'].append(filesMimeType) - - # Base64-encoded NGINX HTTP service configuration - filesNginxMain = {'contents': b64NginxMain, 'name': NcgConfig.config['nms']['config_dir'] + '/nginx.conf'} - filesHttpConf = {'contents': b64HttpConf, - 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ - 'staged_config_http_filename']} - filesStreamConf = {'contents': b64StreamConf, - 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ - 'staged_config_stream_filename']} - - # Append config files to staged configuration - configFiles['files'].append(filesNginxMain) - configFiles['files'].append(filesHttpConf) - configFiles['files'].append(filesStreamConf) - - # Staged config - baseStagedConfig = {'auxFiles': auxFiles, 'configFiles': configFiles} - stagedConfig = {'auxFiles': auxFiles, 'configFiles': configFiles, - 'updateTime': datetime.utcnow().isoformat()[:-3] + 'Z', - 'ignoreConflict': True, 'validateConfig': False} - - currentBaseStagedConfig = NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}').decode('utf-8') if NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}') else None - newBaseStagedConfig = json.dumps(baseStagedConfig) - - if currentBaseStagedConfig is not None and newBaseStagedConfig == currentBaseStagedConfig: - print(f'Declaration [{configUid}] not changed') - return {"status_code": 200, - "message": {"status_code": 200, "message": {"code": 200, "content": "no changes"}}} - else: - # Configuration objects have changed, publish to NIM needed - print(f'Declaration [{configUid}] changed, publishing to NIM' if configUid else f'New declaration created, publishing to NIM') - - # Retrieve instance group uid - try: - ig = requests.get(url=f'{nmsUrl}/api/platform/v1/instance-groups', auth=(nmsUsername, nmsPassword), - verify=False) - except Exception as e: - return {"status_code": 400, - "message": {"status_code": 400, - "message": {"code": 400, "content": f"Can't connect to {nmsUrl}"}}} - - if ig.status_code != 200: - try: - return {"status_code": ig.status_code, - "message": {"status_code": ig.status_code, - "message": {"code": ig.status_code, "content": json.loads(ig.text)}}} - except: - return {"status_code": ig.status_code, - "message": {"status_code": ig.status_code, - "message": {"code": ig.status_code, "content": ig.text}}} - - # Get the instance group id - igUid = v4_2.NIMUtils.getNIMInstanceGroupUid(nmsUrl=nmsUrl, nmsUsername=nmsUsername, - nmsPassword=nmsPassword, instanceGroupName=nmsInstanceGroup) - - # Invalid instance group - if igUid is None: - return {"status_code": 404, - "message": {"status_code": 404, "message": {"code": 404, - "content": f"instance group {nmsInstanceGroup} not found"}}, - "headers": {'Content-Type': 'application/json'}} - - ### NGINX App Protect policies support - commits policies to control plane - - # Check NGINX App Protect WAF policies configuration sanity - status, description = v4_2.NAPUtils.checkDeclarationPolicies(d) + # NGINX auxiliary files for staged config + auxFiles['name'] = NcgConfig.config['nms']['config_dir'] - if status != 200: - return {"status_code": 422, "message": {"status_code": status, "message": {"code": status,"content": description}}, - "headers": {'Content-Type': 'application/json'}} - - # Provision NGINX App Protect WAF policies to NGINX Instance Manager - provisionedNapPolicies, activePolicyUids = v4_2.NAPUtils.provisionPolicies( - nmsUrl=nmsUrl, nmsUsername=nmsUsername, nmsPassword=nmsPassword, declaration=d) - - ### / NGINX App Protect policies support - - ### Publish staged config to instance group - r = requests.post(url=nmsUrl + f"/api/platform/v1/instance-groups/{igUid}/config", - data=json.dumps(stagedConfig), - headers={'Content-Type': 'application/json'}, - auth=(nmsUsername, nmsPassword), - verify=False) - - if r.status_code != 202: - # Configuration push failed - return {"status_code": r.status_code, - "message": {"status_code": r.status_code, "message": r.text}, - "headers": {'Content-Type': 'application/json'}} - - # Fetch the deployment status - publishResponse = json.loads(r.text) - - # Wait for either NIM success or failure after pushing a staged config - isPending = True - while isPending: - time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) - deploymentCheck = requests.get(url=nmsUrl + publishResponse['links']['rel'], - auth=(nmsUsername, nmsPassword), - verify=False) - - checkJson = json.loads(deploymentCheck.text) - - if not checkJson['details']['pending']: - isPending = False - - if len(checkJson['details']['failure']) > 0: - # Staged config publish to NIM failed - jsonResponse = checkJson['details']['failure'][0] - deploymentCheck.status_code = 422 - else: - # Staged config publish to NIM succeeded - jsonResponse = json.loads(deploymentCheck.text) - - # if nmsSynctime > 0 and runfromautosync == False: - if runfromautosync == False: - # No configuration is found, generate one - configUid = str(getuniqueid()) - - # Stores the staged config to redis - # Redis keys: - # ncg.declaration.[configUid] = original config declaration - # ncg.declarationrendered.[configUid] = original config declaration - rendered - # ncg.basestagedconfig.[configUid] = base staged configuration - # ncg.apiversion.[configUid] = ncg API version - # ncg.status.[configUid] = latest status - - NcgRedis.redis.set(f'ncg.declaration.{configUid}', pickle.dumps(declaration)) - NcgRedis.redis.set(f'ncg.declarationrendered.{configUid}', json.dumps(d)) - NcgRedis.redis.set(f'ncg.basestagedconfig.{configUid}', json.dumps(baseStagedConfig)) - NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) - - # Makes NGINX App Protect policies active - doWeHavePolicies = v4_2.NAPUtils.makePolicyActive(nmsUrl=nmsUrl, nmsUsername=nmsUsername, - nmsPassword=nmsPassword, - activePolicyUids=activePolicyUids, - instanceGroupUid=igUid) - - if doWeHavePolicies: - # Clean up NGINX App Protect WAF policies not used anymore - # and not defined in the declaration just pushed - time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) - v4_2.NAPUtils.cleanPolicyLeftovers(nmsUrl=nmsUrl, nmsUsername=nmsUsername, - nmsPassword=nmsPassword, - currentPolicies=provisionedNapPolicies) - - # If deploying a new configuration in GitOps mode start autosync - if nmsSynctime == 0: - NcgRedis.declarationsList[configUid] = "static" - elif not runfromautosync: - # GitOps autosync - print(f'Starting autosync for configUid {configUid} every {nmsSynctime} seconds') - - job = schedule.every(nmsSynctime).seconds.do(lambda: configautosync(configUid)) - # Keep track of GitOps configs, key is the threaded job - NcgRedis.declarationsList[configUid] = job - - NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) - - responseContent = {'code': deploymentCheck.status_code, 'content': jsonResponse, 'configUid': configUid} - - # Configuration push completed, update redis keys - if configUid != "": - NcgRedis.redis.set('ncg.status.' + configUid, json.dumps(responseContent)) - - # if nmsSynctime > 0: - # Updates status, declaration and basestagedconfig in redis - NcgRedis.redis.set('ncg.declaration.' + configUid, pickle.dumps(declaration)) - NcgRedis.redis.set('ncg.declarationrendered.' + configUid, json.dumps(d)) - NcgRedis.redis.set('ncg.basestagedconfig.' + configUid, json.dumps(baseStagedConfig)) - - return {"status_code": deploymentCheck.status_code, - "message": {"status_code": deploymentCheck.status_code, - "message": responseContent}, - "headers": {'Content-Type': 'application/json'} - } + finalReply = v5_2.NGINXOneOutput.NGINXOneOutput(d = d, declaration = declaration, apiversion = apiversion, + b64HttpConf = b64HttpConf, b64StreamConf = b64StreamConf, + configFiles = configFiles, + auxFiles = auxFiles, + runfromautosync = runfromautosync, configUid = configUid ) + + if finalReply['status_code'] == 200: + finalReply['message']['message']['content']['manifests'] = extraOutputManifests + return finalReply else: return {"status_code": 422, "message": {"status_code": 422, "message": f"output type {decltype} unknown"}} @@ -864,51 +689,51 @@ def patch_config(declaration: ConfigDeclaration, configUid: str, apiversion: str status_code, currentDeclaration = get_declaration(configUid=configUid) # Handle policy updates - d_policies = v4_2.MiscUtils.getDictKey(declarationToPatch, 'output.nms.policies') + d_policies = v5_2.MiscUtils.getDictKey(declarationToPatch, 'output.nms.policies') if d_policies is not None: # NGINX App Protect WAF policy updates for p in d_policies: - currentDeclaration = v4_2.DeclarationPatcher.patchNAPPolicies( + currentDeclaration = v5_2.DeclarationPatcher.patchNAPPolicies( sourceDeclaration=currentDeclaration, patchedNAPPolicies=p) # Handle certificate updates - d_certificates = v4_2.MiscUtils.getDictKey(declarationToPatch, 'output.nms.certificates') + d_certificates = v5_2.MiscUtils.getDictKey(declarationToPatch, 'output.nms.certificates') if d_certificates is not None: # TLS certificate/key updates for p in d_certificates: - currentDeclaration = v4_2.DeclarationPatcher.patchCertificates( + currentDeclaration = v5_2.DeclarationPatcher.patchCertificates( sourceDeclaration=currentDeclaration, patchedCertificates=p) # Handle declaration updates if 'declaration' in declarationToPatch: # HTTP - d_upstreams = v4_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.http.upstreams') + d_upstreams = v5_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.http.upstreams') if d_upstreams: # HTTP upstream patch for u in d_upstreams: - currentDeclaration = v4_2.DeclarationPatcher.patchHttpUpstream( + currentDeclaration = v5_2.DeclarationPatcher.patchHttpUpstream( sourceDeclaration=currentDeclaration, patchedHttpUpstream=u) - d_servers = v4_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.http.servers') + d_servers = v5_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.http.servers') if d_servers: # HTTP servers patch for s in d_servers: - currentDeclaration = v4_2.DeclarationPatcher.patchHttpServer( + currentDeclaration = v5_2.DeclarationPatcher.patchHttpServer( sourceDeclaration=currentDeclaration, patchedHttpServer=s) # Stream / Layer4 - d_upstreams = v4_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.layer4.upstreams') + d_upstreams = v5_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.layer4.upstreams') if d_upstreams: # Stream upstream patch for u in d_upstreams: - currentDeclaration = v4_2.DeclarationPatcher.patchStreamUpstream( + currentDeclaration = v5_2.DeclarationPatcher.patchStreamUpstream( sourceDeclaration=currentDeclaration, patchedStreamUpstream=u) - d_servers = v4_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.layer4.servers') + d_servers = v5_2.MiscUtils.getDictKey(declarationToPatch, 'declaration.layer4.servers') if d_servers: # Stream servers patch for s in d_servers: - currentDeclaration = v4_2.DeclarationPatcher.patchStreamServer( + currentDeclaration = v5_2.DeclarationPatcher.patchStreamServer( sourceDeclaration=currentDeclaration, patchedStreamServer=s) # Apply the updated declaration diff --git a/src/V4_2_NginxConfigDeclaration.py b/src/V5_2_NginxConfigDeclaration.py similarity index 85% rename from src/V4_2_NginxConfigDeclaration.py rename to src/V5_2_NginxConfigDeclaration.py index 444e9de..aba4897 100644 --- a/src/V4_2_NginxConfigDeclaration.py +++ b/src/V5_2_NginxConfigDeclaration.py @@ -4,7 +4,7 @@ from __future__ import annotations from typing import List, Optional -from pydantic import BaseModel, Extra, model_validator +from pydantic import BaseModel, model_validator import re @@ -122,27 +122,44 @@ class OutputNMS(BaseModel, extra="forbid"): log_profiles: Optional[List[LogProfile]] = [] +class OutputNGINXOne(BaseModel, extra="forbid"): + url: str = "" + namespace: str = "" + token: str = "" + configsyncgroup: str = "" + synctime: Optional[int] = 0 + modules: Optional[List[str]] = [] + certificates: Optional[List[NmsCertificate]] = [] + policies: Optional[List[NmsPolicy]] = [] + log_profiles: Optional[List[LogProfile]] = [] + + +class License(BaseModel, extra="forbid"): + endpoint: str = "product.connect.nginx.com" + token: str = "" + ssl_verify: bool = True + grace_period: bool = False + + class Output(BaseModel, extra="forbid"): type: str - configmap: Optional[OutputConfigMap] = {} - http: Optional[OutputHttp] = {} + license: Optional[License] = {} nms: Optional[OutputNMS] = {} + nginxone: Optional[OutputNGINXOne] = {} @model_validator(mode='after') def check_type(self) -> 'Output': - _type, configmap, http, nms = self.type, self.configmap, self.http, self.nms + _type,nms, nginxone = self.type, self.nms, self.nginxone - valid = ['plaintext', 'json', 'configmap', 'http', 'nms'] + valid = ['nms', 'nginxone'] if _type not in valid: raise ValueError(f"Invalid output type [{_type}] must be one of {str(valid)}") isError = False - if _type == 'configmap' and not configmap: - isError = True - elif _type == 'http' and not http: + if _type == 'nms' and not nms: isError = True - elif _type == 'nms' and not nms: + elif _type == 'nginxone' and not nginxone: isError = True if isError: @@ -151,7 +168,6 @@ def check_type(self) -> 'Output': return self - class OcspStapling(BaseModel, extra="forbid"): enabled: Optional[bool] = False verify: Optional[bool] = False @@ -302,8 +318,8 @@ class AuthClientJWT(BaseModel, extra="forbid"): def check_type(self) -> 'AuthClientJWT': jwt_type, key = self.jwt_type, self.key - if not key.strip(): - raise ValueError(f"Invalid: JWT key must not be empty") + #if not key.strip(): + # raise ValueError(f"Invalid: JWT key must not be empty") valid = ['signed', 'encrypted', 'nested'] if jwt_type not in valid: @@ -507,6 +523,7 @@ def check_type(self) -> 'Server': class L4Server(BaseModel, extra="forbid"): name: str + resolver: Optional[str] = "" listen: Optional[ListenL4] = {} upstream: Optional[str] = "" snippet: Optional[ObjectFromSourceOfTruth] = {} @@ -542,14 +559,15 @@ class L4Origin(BaseModel, extra="forbid"): server: str weight: Optional[int] = 1 max_fails: Optional[int] = 1 - fail_timeout: Optional[str] = "" + fail_timeout: Optional[str] = "10s" max_conns: Optional[int] = 0 - slow_start: Optional[str] = "" + slow_start: Optional[str] = "0" backup: Optional[bool] = False class Upstream(BaseModel, extra="forbid"): name: str + resolver: Optional[str] = "" origin: Optional[List[Origin]] = [] sticky: Optional[Sticky] = {} snippet: Optional[ObjectFromSourceOfTruth] = {} @@ -566,6 +584,7 @@ def check_type(self) -> 'Upstream': class L4Upstream(BaseModel, extra="forbid"): name: str + resolver: Optional[str] = "" origin: Optional[List[L4Origin]] = [] snippet: Optional[ObjectFromSourceOfTruth] = {} @@ -649,6 +668,15 @@ class Layer4(BaseModel, extra="forbid"): upstreams: Optional[List[L4Upstream]] = [] +class Resolver(BaseModel, extra="forbid"): + name: str + address: str + valid: Optional[str] = "" + ipv4: bool = True + ipv6: bool = True + timeout: str = "30s" + + class Authentication_Client(BaseModel, extra="forbid"): name: str type: str @@ -746,6 +774,7 @@ class Http(BaseModel, extra="forbid"): class Declaration(BaseModel, extra="forbid"): layer4: Optional[Layer4] = {} http: Optional[Http] = {} + resolvers: Optional[List[Resolver]] = [] class API_Gateway(BaseModel, extra="forbid"): @@ -753,14 +782,91 @@ class API_Gateway(BaseModel, extra="forbid"): strip_uri: Optional[bool] = False server_url: Optional[str] = "" + +class DevPortal_Redocly(BaseModel, extra="forbid"): + uri: Optional[str] = "/devportal.html" + + +class DevPortal_Backstage(BaseModel, extra="forbid"): + name: str = "" + lifecycle: Optional[str] = "production" + owner: str = "" + system: Optional[str] = "" + + @model_validator(mode='after') + def check_type(self) -> 'DevPortal_Backstage': + _lifecycle = self.lifecycle + + valid = ['experimental', 'production', 'deprecated'] + if _lifecycle not in valid: + raise ValueError(f"Invalid developer portal type [{_lifecycle}] must be one of {str(valid)}") + + return self + + class DeveloperPortal(BaseModel, extra="forbid"): enabled: Optional[bool] = False - uri: Optional[str] = "/devportal.html" + type: str = "" + redocly: Optional[DevPortal_Redocly] = {} + backstage: Optional[DevPortal_Backstage] = {} + + @model_validator(mode='after') + def check_type(self) -> 'DeveloperPortal': + _enabled, _type, _redocly, _backstage = self.enabled, self.type, self.redocly, self.backstage + + valid = ['redocly', 'backstage'] + + if _enabled == True and _type not in valid: + raise ValueError(f"Invalid developer portal type [{_type}] must be one of {str(valid)}") + + isError = False + + if _type == 'redocly' and not _redocly: + isError = True + + if _type == 'backstage' and not _backstage: + isError = True + + if isError: + raise ValueError(f"Missing developer portal data for type [{_type}]") + + return self + + +class Visibility_Moesif(BaseModel, extra="forbid"): + application_id: str = "" + plugin_path: Optional[str] = "/usr/local/share/lua/5.1/resty/moesif" + + +class Visibility(BaseModel, extra="forbid"): + enabled: Optional[bool] = False + type: str = "" + moesif: Optional[Visibility_Moesif] = {} + + @model_validator(mode='after') + def check_type(self) -> 'Visibility': + _enabled, _type, _moesif = self.enabled, self.type, self.moesif + + valid = ['moesif'] + + if _enabled == True and _type not in valid: + raise ValueError(f"Invalid visibility type [{_type}] must be one of {str(valid)}") + + isError = False + + if _type == 'moesif' and not _moesif: + isError = True + + if isError: + raise ValueError(f"Missing visibility data for type [{_type}]") + + return self class APIGateway(BaseModel, extra="forbid"): openapi_schema: Optional[ObjectFromSourceOfTruth] = {} api_gateway: Optional[API_Gateway] = {} developer_portal: Optional[DeveloperPortal] = {} + visibility: Optional[List[Visibility]] = [] rate_limit: Optional[List[RateLimitApiGw]] = [] authentication: Optional[APIGatewayAuthentication] = {} authorization: Optional[List[APIGatewayAuthorization]] = [] diff --git a/src/main.py b/src/main.py index f20a72e..ba7f736 100644 --- a/src/main.py +++ b/src/main.py @@ -16,15 +16,15 @@ import NcgConfig import NcgRedis -import V4_2_CreateConfig -import V4_2_NginxConfigDeclaration - import V5_0_CreateConfig import V5_0_NginxConfigDeclaration import V5_1_CreateConfig import V5_1_NginxConfigDeclaration +import V5_2_CreateConfig +import V5_2_NginxConfigDeclaration + cfg = NcgConfig.NcgConfig(configFile="../etc/config.toml") redis = NcgRedis.NcgRedis(host=cfg.config['redis']['host'], port=cfg.config['redis']['port']) @@ -42,10 +42,10 @@ def runScheduler(): time.sleep(1) -# Submit declaration using v4.2 API -@app.post("/v4.2/config", status_code=200, response_class=PlainTextResponse) -def post_config_v4_2(d: V4_2_NginxConfigDeclaration.ConfigDeclaration, response: Response): - output = V4_2_CreateConfig.createconfig(declaration=d, apiversion='v4.2') +# Submit declaration using v5.0 API +@app.post("/v5.0/config", status_code=200, response_class=PlainTextResponse) +def post_config_v5_0(d: V5_0_NginxConfigDeclaration.ConfigDeclaration, response: Response): + output = V5_0_CreateConfig.createconfig(declaration=d, apiversion='v5.0') if type(output) in [Response, str]: # ConfigMap or plaintext response @@ -64,10 +64,10 @@ def post_config_v4_2(d: V4_2_NginxConfigDeclaration.ConfigDeclaration, response: return JSONResponse(content=response, status_code=output['status_code'], headers=headers) -# Submit declaration using v5.0 API -@app.post("/v5.0/config", status_code=200, response_class=PlainTextResponse) -def post_config_v5_0(d: V5_0_NginxConfigDeclaration.ConfigDeclaration, response: Response): - output = V5_0_CreateConfig.createconfig(declaration=d, apiversion='v5.0') +# Submit declaration using v5.1 API +@app.post("/v5.1/config", status_code=200, response_class=PlainTextResponse) +def post_config_v5_1(d: V5_1_NginxConfigDeclaration.ConfigDeclaration, response: Response): + output = V5_1_CreateConfig.createconfig(declaration=d, apiversion='v5.1') if type(output) in [Response, str]: # ConfigMap or plaintext response @@ -86,10 +86,10 @@ def post_config_v5_0(d: V5_0_NginxConfigDeclaration.ConfigDeclaration, response: return JSONResponse(content=response, status_code=output['status_code'], headers=headers) -# Submit declaration using v5.1 API -@app.post("/v5.1/config", status_code=200, response_class=PlainTextResponse) -def post_config_v5_1(d: V5_1_NginxConfigDeclaration.ConfigDeclaration, response: Response): - output = V5_1_CreateConfig.createconfig(declaration=d, apiversion='v5.1') +# Submit declaration using v5.2 API +@app.post("/v5.2/config", status_code=200, response_class=PlainTextResponse) +def post_config_v5_2(d: V5_2_NginxConfigDeclaration.ConfigDeclaration, response: Response): + output = V5_2_CreateConfig.createconfig(declaration=d, apiversion='v5.2') if type(output) in [Response, str]: # ConfigMap or plaintext response @@ -108,12 +108,6 @@ def post_config_v5_1(d: V5_1_NginxConfigDeclaration.ConfigDeclaration, response: return JSONResponse(content=response, status_code=output['status_code'], headers=headers) -# Modify declaration using v4.2 API -@app.patch("/v4.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) -def patch_config_v4_2(d: V4_2_NginxConfigDeclaration.ConfigDeclaration, response: Response, configuid: str): - return V4_2_CreateConfig.patch_config(declaration=d, configUid=configuid, apiversion='v4.2') - - # Modify declaration using v5.0 API @app.patch("/v5.0/config/{configuid}", status_code=200, response_class=PlainTextResponse) def patch_config_v5_0(d: V5_0_NginxConfigDeclaration.ConfigDeclaration, response: Response, configuid: str): @@ -126,10 +120,16 @@ def patch_config_v5_1(d: V5_1_NginxConfigDeclaration.ConfigDeclaration, response return V5_1_CreateConfig.patch_config(declaration=d, configUid=configuid, apiversion='v5.1') -# Get declaration - v4.2 API -@app.get("/v4.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) -def get_config_declaration_v4_2(configuid: str): - status_code, content = V4_2_CreateConfig.get_declaration(configUid=configuid) +# Modify declaration using v5.2 API +@app.patch("/v5.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) +def patch_config_v5_2(d: V5_2_NginxConfigDeclaration.ConfigDeclaration, response: Response, configuid: str): + return V5_2_CreateConfig.patch_config(declaration=d, configUid=configuid, apiversion='v5.2') + + +# Get declaration - v5.0 API +@app.get("/v5.0/config/{configuid}", status_code=200, response_class=PlainTextResponse) +def get_config_declaration_v5_0(configuid: str): + status_code, content = V5_0_CreateConfig.get_declaration(configUid=configuid) if status_code == 404: return JSONResponse( @@ -145,10 +145,10 @@ def get_config_declaration_v4_2(configuid: str): ) -# Get declaration - v5.0 API -@app.get("/v5.0/config/{configuid}", status_code=200, response_class=PlainTextResponse) -def get_config_declaration_v5_0(configuid: str): - status_code, content = V5_0_CreateConfig.get_declaration(configUid=configuid) +# Get declaration - v5.1 API +@app.get("/v5.1/config/{configuid}", status_code=200, response_class=PlainTextResponse) +def get_config_declaration_v5_1(configuid: str): + status_code, content = V5_1_CreateConfig.get_declaration(configUid=configuid) if status_code == 404: return JSONResponse( @@ -164,10 +164,10 @@ def get_config_declaration_v5_0(configuid: str): ) -# Get declaration - v5.1 API -@app.get("/v5.1/config/{configuid}", status_code=200, response_class=PlainTextResponse) -def get_config_declaration_v5_1(configuid: str): - status_code, content = V5_1_CreateConfig.get_declaration(configUid=configuid) +# Get declaration - v5.2 API +@app.get("/v5.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) +def get_config_declaration_v5_2(configuid: str): + status_code, content = V5_2_CreateConfig.get_declaration(configUid=configuid) if status_code == 404: return JSONResponse( @@ -184,9 +184,9 @@ def get_config_declaration_v5_1(configuid: str): # Get declaration status -@app.get("/v4.2/config/{configuid}/status", status_code=200, response_class=PlainTextResponse) @app.get("/v5.0/config/{configuid}/status", status_code=200, response_class=PlainTextResponse) @app.get("/v5.1/config/{configuid}/status", status_code=200, response_class=PlainTextResponse) +@app.get("/v5.2/config/{configuid}/status", status_code=200, response_class=PlainTextResponse) def get_config_status(configuid: str): status = redis.redis.get('ncg.status.' + configuid) @@ -205,9 +205,9 @@ def get_config_status(configuid: str): # Delete declaration -@app.delete("/v4.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) @app.delete("/v5.0/config/{configuid}", status_code=200, response_class=PlainTextResponse) @app.delete("/v5.1/config/{configuid}", status_code=200, response_class=PlainTextResponse) +@app.delete("/v5.2/config/{configuid}", status_code=200, response_class=PlainTextResponse) def delete_config(configuid: str = ""): if configuid not in redis.declarationsList: return JSONResponse( diff --git a/src/v5_0/NGINXOneOutput.py b/src/v5_0/NGINXOneOutput.py index 72199d5..7819c71 100644 --- a/src/v5_0/NGINXOneOutput.py +++ b/src/v5_0/NGINXOneOutput.py @@ -166,10 +166,10 @@ def NGINXOneOutput(d, declaration: ConfigDeclaration, apiversion: str, b64HttpCo # Staged config baseStagedConfig = {'aux': [ { 'files': configFiles } ] } - #stagedConfig = {'conf_path': NcgConfig.config['nms']['nginx_conf'], + #stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', # 'aux': [ auxFiles ], # 'configs': [ configFiles ]} - stagedConfig = {'conf_path': NcgConfig.config['nms']['nginx_conf'], + stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', 'configs': [ configFiles, auxFiles ]} currentBaseStagedConfig = NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}').decode( diff --git a/src/v5_1/NGINXOneOutput.py b/src/v5_1/NGINXOneOutput.py index fe9290c..f5c1ecd 100644 --- a/src/v5_1/NGINXOneOutput.py +++ b/src/v5_1/NGINXOneOutput.py @@ -166,10 +166,10 @@ def NGINXOneOutput(d, declaration: ConfigDeclaration, apiversion: str, b64HttpCo # Staged config baseStagedConfig = {'aux': [ { 'files': configFiles } ] } - #stagedConfig = {'conf_path': NcgConfig.config['nms']['nginx_conf'], + #stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', # 'aux': [ auxFiles ], # 'configs': [ configFiles ]} - stagedConfig = {'conf_path': NcgConfig.config['nms']['nginx_conf'], + stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', 'configs': [ configFiles, auxFiles ]} currentBaseStagedConfig = NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}').decode( diff --git a/src/v4_2/APIGateway.py b/src/v5_2/APIGateway.py similarity index 73% rename from src/v4_2/APIGateway.py rename to src/v5_2/APIGateway.py index aead426..acbd92f 100644 --- a/src/v4_2/APIGateway.py +++ b/src/v5_2/APIGateway.py @@ -4,12 +4,13 @@ import json -import v4_2.GitOps -import v4_2.MiscUtils -from v4_2.OpenAPIParser import OpenAPIParser +import v5_2.GitOps +import v5_2.MiscUtils +from v5_2.OpenAPIParser import OpenAPIParser # pydantic models -from V4_2_NginxConfigDeclaration import * +# pydantic models +from V5_2_NginxConfigDeclaration import * # Builds the declarative JSON for the API Gateway configuration @@ -18,12 +19,12 @@ def createAPIGateway(locationDeclaration: dict, authProfiles: Authentication={}) apiGwDeclaration = {} if locationDeclaration['apigateway']['openapi_schema']: - status, apiSchemaString = v4_2.GitOps.getObjectFromRepo(object=locationDeclaration['apigateway']['openapi_schema'], + status, apiSchemaString = v5_2.GitOps.getObjectFromRepo(object=locationDeclaration['apigateway']['openapi_schema'], authProfiles = authProfiles['server'] if 'server' in authProfiles else {}, base64Encode=False) - if v4_2.MiscUtils.yaml_or_json(apiSchemaString['content']) == 'yaml': + if v5_2.MiscUtils.yaml_or_json(apiSchemaString['content']) == 'yaml': # YAML to JSON conversion - apiSchemaString['content'] = v4_2.MiscUtils.yaml_to_json(apiSchemaString['content']) + apiSchemaString['content'] = v5_2.MiscUtils.yaml_to_json(apiSchemaString['content']) apiSchema = OpenAPIParser(json.loads(apiSchemaString['content'])) @@ -34,4 +35,4 @@ def createAPIGateway(locationDeclaration: dict, authProfiles: Authentication={}) apiGwDeclaration['paths'] = apiSchema.paths() apiGwDeclaration['version'] = apiSchema.version() - return 200, apiGwDeclaration \ No newline at end of file + return 200, apiGwDeclaration, apiSchemaString['content'] \ No newline at end of file diff --git a/src/v4_2/DeclarationPatcher.py b/src/v5_2/DeclarationPatcher.py similarity index 97% rename from src/v4_2/DeclarationPatcher.py rename to src/v5_2/DeclarationPatcher.py index 6e27285..51260a4 100644 --- a/src/v4_2/DeclarationPatcher.py +++ b/src/v5_2/DeclarationPatcher.py @@ -214,13 +214,13 @@ def patchCertificates(sourceDeclaration: dict, patchedCertificates: dict): # TLS certificates patch for c in sourceDeclaration['output']['nms']['certificates']: - if 'type' in c and c['type'] in ['certificate', 'key', 'chain'] \ + if 'type' in c and c['type'] in ['certificate', 'key'] \ and 'name' in c and c['name'] \ and c['type'] == patchedCertificates['type'] \ and c['name'] == patchedCertificates['name']: if 'contents' in c and c['contents']: - # Patching an existing TLS certificate/key/chain, 'name' is the key. + # Patching an existing TLS certificate/key, 'name' is the key. # If content is empty the certificate is deleted allTargetCertificates.append(patchedCertificates) @@ -230,7 +230,7 @@ def patchCertificates(sourceDeclaration: dict, patchedCertificates: dict): allTargetCertificates.append(c) if not haveWePatched: - # The TLS certificate/key/chain being patched is a new one, let's add it + # The TLS certificate/key being patched is a new one, let's add it allTargetCertificates.append(patchedCertificates) sourceDeclaration['output']['nms']['certificates'] = allTargetCertificates diff --git a/src/v4_2/DevPortal.py b/src/v5_2/DevPortal.py similarity index 84% rename from src/v4_2/DevPortal.py rename to src/v5_2/DevPortal.py index 7791ce4..a20546e 100644 --- a/src/v4_2/DevPortal.py +++ b/src/v5_2/DevPortal.py @@ -8,11 +8,11 @@ # NGINX Declarative API modules from NcgConfig import NcgConfig -import v4_2.GitOps -import v4_2.MiscUtils +import v5_2.GitOps +import v5_2.MiscUtils # pydantic models -from V4_2_NginxConfigDeclaration import * +from V5_2_NginxConfigDeclaration import * def buildDevPortal(openapischema): try: @@ -29,12 +29,12 @@ def buildDevPortal(openapischema): # Return a tuple: status, description. If status = 200 things were successful def createDevPortal(locationDeclaration: dict, authProfiles: Authentication={}): if locationDeclaration['apigateway']['openapi_schema']: - status, apiSchemaString = v4_2.GitOps.getObjectFromRepo( + status, apiSchemaString = v5_2.GitOps.getObjectFromRepo( object = locationDeclaration['apigateway']['openapi_schema'], authProfiles = authProfiles['server'] if 'server' in authProfiles else {}, base64Encode = False) - if v4_2.MiscUtils.yaml_or_json(apiSchemaString['content']) == 'yaml': + if v5_2.MiscUtils.yaml_or_json(apiSchemaString['content']) == 'yaml': # YAML to JSON conversion - status, devportalJSON = buildDevPortal(openapischema = v4_2.MiscUtils.yaml_to_json(apiSchemaString['content'])) + status, devportalJSON = buildDevPortal(openapischema = v5_2.MiscUtils.yaml_to_json(apiSchemaString['content'])) else: status, devportalJSON = buildDevPortal(openapischema = apiSchemaString['content']) diff --git a/src/v4_2/GitOps.py b/src/v5_2/GitOps.py similarity index 97% rename from src/v4_2/GitOps.py rename to src/v5_2/GitOps.py index 473c577..ec1ac85 100644 --- a/src/v4_2/GitOps.py +++ b/src/v5_2/GitOps.py @@ -6,15 +6,15 @@ import requests from requests import ReadTimeout, HTTPError, Timeout, ConnectionError, ConnectTimeout -from typing import List # pydantic models -from V4_2_NginxConfigDeclaration import * +from V5_2_NginxConfigDeclaration import * # Fetches a URL content def __fetchfromsourceoftruth__(url, headers = {} ): # Object is fetched from external repository + try: reply = requests.get(url = url, headers = headers, verify=False) except (ConnectTimeout, HTTPError, ReadTimeout, Timeout, ConnectionError): diff --git a/src/v4_2/MiscUtils.py b/src/v5_2/MiscUtils.py similarity index 78% rename from src/v4_2/MiscUtils.py rename to src/v5_2/MiscUtils.py index a5ea547..424d98e 100644 --- a/src/v4_2/MiscUtils.py +++ b/src/v5_2/MiscUtils.py @@ -5,6 +5,8 @@ import re import json import yaml +import uuid + def getDictKey(_dict: dict, key_lookup: str, separator='.'): """ @@ -41,4 +43,18 @@ def yaml_or_json(document: str): YAML to JSON conversion """ def yaml_to_json(document: str): - return json.dumps(yaml.safe_load(document)) \ No newline at end of file + return json.dumps(yaml.safe_load(document)) + + +""" +JSON TO YAML conversion +""" +def json_to_yaml(document: str): + return yaml.dump(json.loads(document)) + + +""" +Returns a unique ID +""" +def getuniqueid(): + return uuid.uuid4() \ No newline at end of file diff --git a/src/v4_2/NAPUtils.py b/src/v5_2/NAPUtils.py similarity index 89% rename from src/v4_2/NAPUtils.py rename to src/v5_2/NAPUtils.py index 4e76e0d..ed06fda 100644 --- a/src/v4_2/NAPUtils.py +++ b/src/v5_2/NAPUtils.py @@ -4,8 +4,11 @@ import requests import json +import base64 -import v4_2.GitOps +import v5_2.GitOps + +from NcgConfig import NcgConfig from fastapi.responses import Response, JSONResponse @@ -144,7 +147,7 @@ def checkDeclarationPolicies(declaration: dict): return 200, "" -# For the given declaration creates/updates NGINX App Protect WAF policies on NGINX Management Suite +# For the given declaration creates/updates NGINX App Protect WAF policies on NGINX Instance Manager # making sure that they are in sync with what is defined in the JSON declaration # Returns a tuple with two dictionaries: all_policy_names_and_versions, all_policy_active_names_and_uids def provisionPolicies(nmsUrl: str, nmsUsername: str, nmsPassword: str, declaration: dict): @@ -171,7 +174,7 @@ def provisionPolicies(nmsUrl: str, nmsUsername: str, nmsPassword: str, declarati if p['type'] == 'app_protect': # Iterates over all policy versions for policyVersion in p['versions']: - status, policyBody = v4_2.GitOps.getObjectFromRepo(policyVersion['contents']) + status, policyBody = v5_2.GitOps.getObjectFromRepo(policyVersion['contents']) if status != 200: return JSONResponse( @@ -240,7 +243,7 @@ def makePolicyActive(nmsUrl: str, nmsUsername: str, nmsPassword: str, activePoli return doWeHavePolicies -# For the given declaration creates/updates NGINX App Protect WAF policies on NGINX Management Suite +# For the given declaration creates/updates NGINX App Protect WAF policies on NGINX Instance Manager # making sure that they are in sync with what is defined in the JSON declaration # Returns a tuple: status, response payload def cleanPolicyLeftovers(nmsUrl: str, nmsUsername: str, nmsPassword: str, currentPolicies: dict): @@ -267,3 +270,38 @@ def cleanPolicyLeftovers(nmsUrl: str, nmsUsername: str, nmsPassword: str, curren __deletePolicy__(nmsUrl=nmsUrl, nmsUsername=nmsUsername, nmsPassword=nmsPassword, policyUid=uid) return + + +# Compile a NGINX App Protect policy and optional user-defined signatures using NGINX App Protect 5 compiler +# https://docs.nginx.com/nginx-app-protect-waf/v5/admin-guide/compiler/ +# +# Global settings: +# { +# "waf-settings": { +# "cookie-protection": { +# "seed": "80miIOiSeXfvNBiDJV4t" +# }, +# "user-defined-signatures": [ +# { +# "$ref": "file:///policies/uds.json" +# } +# ] +# } +# } +def compilePolicy(napPolicy: str, customSignatures: str): + b64napPolicy = base64.b64encode(bytes(napPolicy, 'utf-8')).decode('utf-8') + b64customSignatures = base64.b64encode(bytes(customSignatures, 'utf-8')).decode('utf-8') + cookieProtectionSeed = NcgConfig.config['nap']['cookie_protection_seed'] + + payload = {} + payload['user-signatures'] = b64customSignatures + payload['policy'] = b64napPolicy + payload['cookie-protection-seed'] = cookieProtectionSeed + + try: + response = requests.post(f"http://{NcgConfig.config['nap']['compiler_host']}:{NcgConfig.config['nap']['compiler_port']}{NcgConfig.config['nap']['compiler_uri']}", + headers={'Content-Type': 'application/json'}, data=json.dumps(payload)) + except Exception as e: + return 400, str(e) + + return response \ No newline at end of file diff --git a/src/v5_2/NGINXOneOutput.py b/src/v5_2/NGINXOneOutput.py new file mode 100644 index 0000000..612ab05 --- /dev/null +++ b/src/v5_2/NGINXOneOutput.py @@ -0,0 +1,325 @@ +""" +Output to NGINX One SaaS console +""" + +import base64 +import requests +import json +import pickle +import time +import schedule + +from jinja2 import Environment, FileSystemLoader +from urllib.parse import urlparse +from datetime import datetime + +import V5_2_CreateConfig + +import v5_2.APIGateway +import v5_2.DevPortal +import v5_2.DeclarationPatcher +import v5_2.GitOps +import v5_2.MiscUtils +import v5_2.NMSOutput + +# pydantic models +from V5_2_NginxConfigDeclaration import * + +# NGINX App Protect helper functions +import v5_2.NAPUtils +import v5_2.NGINXOneUtils +import v5_2.MiscUtils + +# NGINX Declarative API modules +from NcgConfig import NcgConfig +from NcgRedis import NcgRedis + +def NGINXOneOutput(d, declaration: ConfigDeclaration, apiversion: str, b64HttpConf: str, + b64StreamConf: str,configFiles = {}, auxFiles = {}, + runfromautosync: bool = False, + configUid: str = ""): + # NGINX One Cloud Console Staged Configuration publish + + nOneToken = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.token') + nOneConfigSyncGroup = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.configsyncgroup') + nOneNamespace = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.namespace') + + nOneSynctime = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.synctime') + + nOneUrlFromJson = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.url') + urlCheck = urlparse(nOneUrlFromJson) + + if urlCheck.scheme not in ['http', 'https'] or urlCheck.scheme == "" or urlCheck.netloc == "": + return {"status_code": 400, + "message": {"status_code": 400, "message": {"code": 400, + "content": f"invalid NGINX One URL {nOneUrlFromJson}"}}, + "headers": {'Content-Type': 'application/json'}} + + nOneUrl = f"{urlCheck.scheme}://{urlCheck.netloc}" + + if nOneSynctime < 0: + return {"status_code": 400, + "message": {"status_code": 400, "message": {"code": 400, "content": "synctime must be >= 0"}}, + "headers": {'Content-Type': 'application/json'}} + + # Fetch NGINX App Protect WAF policies from source of truth if needed + # TODO: d_policies = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.policies') + # NGINX App Protect ignored for NGINX One + + # Check TLS items validity + all_tls = {'certificate': {}, 'key': {}} + + d_certs = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.certificates') + if d_certs is not None: + for i in range(len(d_certs)): + if d_certs[i]['name']: + all_tls[d_certs[i]['type']][d_certs[i]['name']] = True + + d_servers = v5_2.MiscUtils.getDictKey(d, 'declaration.http.servers') + if d_servers is not None: + for server in d_servers: + if server['listen'] is not None: + if 'tls' in server['listen']: + cert_name = v5_2.MiscUtils.getDictKey(server, 'listen.tls.certificate') + if cert_name and cert_name not in all_tls['certificate']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid TLS certificate " + + cert_name + " for server" + str( + server['names'])} + }} + + cert_key = v5_2.MiscUtils.getDictKey(server, 'listen.tls.key') + if cert_key and cert_key not in all_tls['key']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid TLS key " + cert_key + " for server" + str( + server['names'])} + }} + + trusted_cert_name = v5_2.MiscUtils.getDictKey(server, 'listen.tls.trusted_ca_certificates') + if trusted_cert_name and trusted_cert_name not in all_tls['certificate']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid trusted CA certificate " + + trusted_cert_name + " for server" + str(server['names'])} + }} + + # Add optional certificates specified under output.nginxone.certificates + extensions_map = {'certificate': '.crt', 'key': '.key'} + + d_certificates = v5_2.MiscUtils.getDictKey(d, 'output.nginxone.certificates') + if d_certificates is not None: + for c in d_certificates: + status, certContent = v5_2.GitOps.getObjectFromRepo(object=c['contents'], + authProfiles=d['declaration']['http']['authentication']) + + if status != 200: + return {"status_code": 422, + "message": {"status_code": status, "message": {"code": status, "content": certContent}}} + + newAuxFile = {'contents': certContent['content'], 'name': NcgConfig.config['nms']['certs_dir'] + + '/' + c['name'] + extensions_map[c['type']]} + auxFiles['files'].append(newAuxFile) + + ### / Add optional certificates specified under output.nginxone.certificates + + # NGINX main configuration file through template + j2_env = Environment(loader=FileSystemLoader(NcgConfig.config['templates']['root_dir'] + '/' + apiversion), + trim_blocks=True, extensions=["jinja2_base64_filters.Base64Filters"]) + + nginxMainConf = j2_env.get_template(NcgConfig.config['templates']['nginxmain']).render( + nginxconf={'modules': v5_2.MiscUtils.getDictKey(d, 'output.nginxone.modules'), + 'license': v5_2.MiscUtils.getDictKey(d, 'output.license')}) + + # Base64-encoded NGINX main configuration (/etc/nginx/nginx.conf) + b64NginxMain = str(base64.urlsafe_b64encode(nginxMainConf.encode("utf-8")), "utf-8") + + # NGINX License file + licenseJwtFile = j2_env.get_template(NcgConfig.config['templates']['license']).render( + nginxconf={'license': v5_2.MiscUtils.getDictKey(d, 'output.license')}) + + # Base64-encoded license file (/etc/nginx/license.jwt) + b64licenseJwtFile = str(base64.urlsafe_b64encode(licenseJwtFile.encode("utf-8")), "utf-8") + + # Base64-encoded NGINX mime.types (/etc/nginx/mime.types) + f = open(NcgConfig.config['templates']['root_dir'] + '/' + apiversion + '/' + NcgConfig.config['templates'][ + 'mimetypes'], 'r') + nginxMimeTypes = f.read() + f.close() + + b64NginxMimeTypes = str(base64.urlsafe_b64encode(nginxMimeTypes.encode("utf-8")), "utf-8") + filesMimeType = {'contents': b64NginxMimeTypes, 'name': NcgConfig.config['nms']['config_dir'] + '/mime.types'} + auxFiles['files'].append(filesMimeType) + + # Base64-encoded NGINX HTTP service configuration + filesNginxMain = {'contents': b64NginxMain, 'name': NcgConfig.config['nms']['config_dir'] + '/nginx.conf'} + filesLicenseFile = {'contents': b64licenseJwtFile, 'name': NcgConfig.config['nms']['config_dir'] + '/license.jwt'} + filesHttpConf = {'contents': b64HttpConf, + 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ + 'staged_config_http_filename']} + filesStreamConf = {'contents': b64StreamConf, + 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ + 'staged_config_stream_filename']} + + # Append config files to staged configuration + configFiles['files'].append(filesNginxMain) + configFiles['files'].append(filesLicenseFile) + configFiles['files'].append(filesHttpConf) + configFiles['files'].append(filesStreamConf) + + # Staged config + baseStagedConfig = {'aux': [ { 'files': configFiles } ] } + #stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', + # 'aux': [ auxFiles ], + # 'configs': [ configFiles ]} + stagedConfig = {'conf_path': NcgConfig.config['nms']['config_dir'] + '/nginx.conf', + 'configs': [ configFiles, auxFiles ]} + + currentBaseStagedConfig = NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}').decode( + 'utf-8') if NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}') else None + newBaseStagedConfig = json.dumps(baseStagedConfig) + + if currentBaseStagedConfig is not None and newBaseStagedConfig == currentBaseStagedConfig: + print(f'Declaration [{configUid}] not changed') + return {"status_code": 200, + "message": {"status_code": 200, "message": {"code": 200, "content": "no changes"}}} + else: + # Configuration objects have changed, publish to NGINX One needed + print( + f'Declaration [{configUid}] changed, publishing' if configUid else f'New declaration created, publishing') + + # Get the instance group id nOneUrl: str, nOneTokenUsername: str, nameSpace: str, clusterName: str + returnCode, igUid = v5_2.NGINXOneUtils.getConfigSyncGroupId(nOneUrl = nOneUrl, nOneToken = nOneToken, + nameSpace = nOneNamespace, configSyncGroupName = nOneConfigSyncGroup) + + # Invalid instance group + if returnCode != 200: + return {"status_code": 404, + "message": {"status_code": 404, "message": {"code": returnCode, + "content": igUid}}, + "headers": {'Content-Type': 'application/json'}} + + ## TODO: NGINX App Protect not supported with NGINX One + #### NGINX App Protect policies support - commits policies to control plane + # + ## Check NGINX App Protect WAF policies configuration sanity + #status, description = v5_2.NAPUtils.checkDeclarationPolicies(d) + # + #if status != 200: + # return {"status_code": 422, + # "message": {"status_code": status, "message": {"code": status, "content": description}}, + # "headers": {'Content-Type': 'application/json'}} + # + ## Provision NGINX App Protect WAF policies to NGINX Instance Manager + #provisionedNapPolicies, activePolicyUids = v5_2.NAPUtils.provisionPolicies( + # nmsUrl=nmsUrl, nmsUsername=nmsUsername, nmsPassword=nmsPassword, declaration=d) + # + #### / NGINX App Protect policies support + + ### Publish staged config to config sync group + r = requests.put(url=f'{nOneUrl}/api/nginx/one/namespaces/{nOneNamespace}/config-sync-groups/{igUid}/config', + data=json.dumps(stagedConfig), + headers={'Content-Type': 'application/json', "Authorization": f"Bearer APIToken {nOneToken}"}, + verify=False) + + if r.status_code != 202: + # Configuration push failed + return {"status_code": r.status_code, + "message": {"status_code": r.status_code, "message": r.text}, + "headers": {'Content-Type': 'application/json'}} + + # Fetch the deployment status + publishResponse = json.loads(r.text) + publication_id = publishResponse['object_id'] + + # Wait for either NGINX One Cloud Console success or failure after pushing a staged config + isPending = True + while isPending: + time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) + deploymentCheck = requests.get(url=f'{nOneUrl}/api/nginx/one/namespaces/{nOneNamespace}/config-sync-groups/{igUid}/publications/{publication_id}', + headers={"Authorization": f"Bearer APIToken {nOneToken}"}, + verify=False) + + checkJson = json.loads(deploymentCheck.text) + + if not checkJson['status'] == 'pending': + isPending = False + + if checkJson['status'] == "failed": + # Staged config publish to NGINX One failed + jsonResponse = checkJson['status_reasons'][0] + deploymentCheck.status_code = 422 + else: + # Staged config publish to NGINX One succeeded + jsonResponse = json.loads(deploymentCheck.text) + + # if nmsSynctime > 0 and runfromautosync == False: + if runfromautosync == False: + # No configuration is found, generate one + configUid = str(v5_2.MiscUtils.getuniqueid()) + + # Stores the staged config to redis + # Redis keys: + # ncg.declaration.[configUid] = original config declaration + # ncg.declarationrendered.[configUid] = original config declaration - rendered + # ncg.basestagedconfig.[configUid] = base staged configuration + # ncg.apiversion.[configUid] = ncg API version + # ncg.status.[configUid] = latest status + + NcgRedis.redis.set(f'ncg.declaration.{configUid}', pickle.dumps(declaration)) + NcgRedis.redis.set(f'ncg.declarationrendered.{configUid}', json.dumps(d)) + NcgRedis.redis.set(f'ncg.basestagedconfig.{configUid}', json.dumps(baseStagedConfig)) + NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) + + # TODO: NGINX App Protect not supported with NGINX One + ## Makes NGINX App Protect policies active + #doWeHavePolicies = v5_2.NAPUtils.makePolicyActive(nmsUrl=nmsUrl, nmsUsername=nmsUsername, + # nmsPassword=nmsPassword, + # activePolicyUids=activePolicyUids, + # instanceGroupUid=igUid) + # + #if doWeHavePolicies: + # # Clean up NGINX App Protect WAF policies not used anymore + # # and not defined in the declaration just pushed + # time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) + # v5_2.NAPUtils.cleanPolicyLeftovers(nmsUrl=nmsUrl, nmsUsername=nmsUsername, + # nmsPassword=nmsPassword, + # currentPolicies=provisionedNapPolicies) + + # If deploying a new configuration in GitOps mode start autosync + if nOneSynctime == 0: + NcgRedis.declarationsList[configUid] = "static" + elif not runfromautosync: + # GitOps autosync + print(f'Starting autosync for configUid {configUid} every {nOneSynctime} seconds') + + job = schedule.every(nOneSynctime).seconds.do(lambda: V5_2_CreateConfig.configautosync(configUid)) + # Keep track of GitOps configs, key is the threaded job + NcgRedis.declarationsList[configUid] = job + + NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) + + responseContent = {'code': deploymentCheck.status_code, 'content': jsonResponse, 'configUid': configUid} + + # Configuration push completed, update redis keys + if configUid != "": + NcgRedis.redis.set('ncg.status.' + configUid, json.dumps(responseContent)) + + # if nmsSynctime > 0: + # Updates status, declaration and basestagedconfig in redis + NcgRedis.redis.set('ncg.declaration.' + configUid, pickle.dumps(declaration)) + NcgRedis.redis.set('ncg.declarationrendered.' + configUid, json.dumps(d)) + NcgRedis.redis.set('ncg.basestagedconfig.' + configUid, json.dumps(baseStagedConfig)) + + return {"status_code": deploymentCheck.status_code, + "message": {"status_code": deploymentCheck.status_code, + "message": responseContent}, + "headers": {'Content-Type': 'application/json'} + } \ No newline at end of file diff --git a/src/v5_2/NGINXOneUtils.py b/src/v5_2/NGINXOneUtils.py new file mode 100644 index 0000000..a1adbf1 --- /dev/null +++ b/src/v5_2/NGINXOneUtils.py @@ -0,0 +1,32 @@ +""" +NGINX One support functions +""" + +import requests +import json + + +# Fetch a cluster ID from NGINX One +# Return None if not found +def getConfigSyncGroupId(nOneUrl: str, nOneToken: str, nameSpace: str, configSyncGroupName: str): + # Retrieve config sync group uid + cSyncGroup = requests.get(url=f'{nOneUrl}/api/nginx/one/namespaces/{nameSpace}/config-sync-groups', + verify=False, headers = {"Authorization": f"Bearer APIToken {nOneToken}"}) + + if cSyncGroup.status_code != 200: + if cSyncGroup.status_code == 401: + return cSyncGroup.status_code, "NGINX One authentication failed" + else: + return cSyncGroup.status_code, f"Error fetching config sync group uid: {cSyncGroup.text}" + + # Get the instance group id + igUid = None + igJson = json.loads(cSyncGroup.text) + for i in igJson['items']: + if i['name'] == configSyncGroupName: + igUid = i['object_id'] + + if igUid is None: + return 404, f"config sync group [{configSyncGroupName}] not found" + + return 200, igUid diff --git a/src/v4_2/NIMUtils.py b/src/v5_2/NIMUtils.py similarity index 90% rename from src/v4_2/NIMUtils.py rename to src/v5_2/NIMUtils.py index 68d6ad7..de1b9a9 100644 --- a/src/v4_2/NIMUtils.py +++ b/src/v5_2/NIMUtils.py @@ -5,10 +5,6 @@ import requests import json -import v4_2.GitOps - -from fastapi.responses import Response, JSONResponse - # Fetch an instance group UID from NGINX Instance Manager # Return None if not found diff --git a/src/v5_2/NMSOutput.py b/src/v5_2/NMSOutput.py new file mode 100644 index 0000000..34a2f32 --- /dev/null +++ b/src/v5_2/NMSOutput.py @@ -0,0 +1,331 @@ +""" +Output to NGINX Instance Manager +""" + +import base64 +import requests +import json +import pickle +import time +import schedule + +from jinja2 import Environment, FileSystemLoader +from urllib.parse import urlparse +from datetime import datetime + +import V5_2_CreateConfig + +import v5_2.APIGateway +import v5_2.DevPortal +import v5_2.DeclarationPatcher +import v5_2.GitOps +import v5_2.MiscUtils +import v5_2.NMSOutput + +# pydantic models +from V5_2_NginxConfigDeclaration import * + +# NGINX App Protect helper functions +import v5_2.NAPUtils +import v5_2.NIMUtils +import v5_2.MiscUtils + +# NGINX Declarative API modules +from NcgConfig import NcgConfig +from NcgRedis import NcgRedis + +def NMSOutput(d, declaration: ConfigDeclaration, apiversion: str, b64HttpConf: str, + b64StreamConf: str,configFiles = {}, auxFiles = {}, + runfromautosync: bool = False, + configUid: str = ""): + # NGINX Instance Manager Staged Configuration publish + + nmsUsername = v5_2.MiscUtils.getDictKey(d, 'output.nms.username') + nmsPassword = v5_2.MiscUtils.getDictKey(d, 'output.nms.password') + nmsInstanceGroup = v5_2.MiscUtils.getDictKey(d, 'output.nms.instancegroup') + nmsSynctime = v5_2.MiscUtils.getDictKey(d, 'output.nms.synctime') + + nmsUrlFromJson = v5_2.MiscUtils.getDictKey(d, 'output.nms.url') + urlCheck = urlparse(nmsUrlFromJson) + + if urlCheck.scheme not in ['http', 'https'] or urlCheck.scheme == "" or urlCheck.netloc == "": + return {"status_code": 400, + "message": {"status_code": 400, "message": {"code": 400, + "content": f"invalid NGINX Instance Manager URL {nmsUrlFromJson}"}}, + "headers": {'Content-Type': 'application/json'}} + + nmsUrl = f"{urlCheck.scheme}://{urlCheck.netloc}" + + if nmsSynctime < 0: + return {"status_code": 400, + "message": {"status_code": 400, "message": {"code": 400, "content": "synctime must be >= 0"}}, + "headers": {'Content-Type': 'application/json'}} + + # Fetch NGINX App Protect WAF policies from source of truth if needed + d_policies = v5_2.MiscUtils.getDictKey(d, 'output.nms.policies') + if d_policies is not None: + for policy in d_policies: + if 'versions' in policy: + for policyVersion in policy['versions']: + status, content = v5_2.GitOps.getObjectFromRepo(object=policyVersion['contents'], + authProfiles=d['declaration']['http'][ + 'authentication']) + + if status != 200: + return {"status_code": 422, "message": {"status_code": status, "message": content}} + + policyVersion['contents'] = content + + # Check TLS items validity + all_tls = {'certificate': {}, 'key': {}} + + d_certs = v5_2.MiscUtils.getDictKey(d, 'output.nms.certificates') + if d_certs is not None: + for i in range(len(d_certs)): + if d_certs[i]['name']: + all_tls[d_certs[i]['type']][d_certs[i]['name']] = True + + d_servers = v5_2.MiscUtils.getDictKey(d, 'declaration.http.servers') + if d_servers is not None: + for server in d_servers: + if server['listen'] is not None: + if 'tls' in server['listen']: + cert_name = v5_2.MiscUtils.getDictKey(server, 'listen.tls.certificate') + if cert_name and cert_name not in all_tls['certificate']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid TLS certificate " + + cert_name + " for server" + str( + server['names'])} + }} + + cert_key = v5_2.MiscUtils.getDictKey(server, 'listen.tls.key') + if cert_key and cert_key not in all_tls['key']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid TLS key " + cert_key + " for server" + str( + server['names'])} + }} + + trusted_cert_name = v5_2.MiscUtils.getDictKey(server, 'listen.tls.trusted_ca_certificates') + if trusted_cert_name and trusted_cert_name not in all_tls['certificate']: + return {"status_code": 422, + "message": { + "status_code": 422, + "message": {"code": 422, + "content": "invalid trusted CA certificate " + + trusted_cert_name + " for server" + str(server['names'])} + }} + + # Add optional certificates specified under output.nms.certificates + extensions_map = {'certificate': '.crt', 'key': '.key'} + + d_certificates = v5_2.MiscUtils.getDictKey(d, 'output.nms.certificates') + if d_certificates is not None: + for c in d_certificates: + status, certContent = v5_2.GitOps.getObjectFromRepo(object=c['contents'], + authProfiles=d['declaration']['http']['authentication']) + + if status != 200: + return {"status_code": 422, + "message": {"status_code": status, "message": {"code": status, "content": certContent}}} + + newAuxFile = {'contents': certContent['content'], 'name': NcgConfig.config['nms']['certs_dir'] + + '/' + c['name'] + extensions_map[c['type']]} + auxFiles['files'].append(newAuxFile) + + ### / Add optional certificates specified under output.nms.certificates + + # NGINX main configuration file through template + j2_env = Environment(loader=FileSystemLoader(NcgConfig.config['templates']['root_dir'] + '/' + apiversion), + trim_blocks=True, extensions=["jinja2_base64_filters.Base64Filters"]) + + nginxMainConf = j2_env.get_template(NcgConfig.config['templates']['nginxmain']).render( + nginxconf={'modules': v5_2.MiscUtils.getDictKey(d, 'output.nms.modules'), + 'license': v5_2.MiscUtils.getDictKey(d, 'output.license')}) + + # Base64-encoded NGINX main configuration (/etc/nginx/nginx.conf) + b64NginxMain = str(base64.urlsafe_b64encode(nginxMainConf.encode("utf-8")), "utf-8") + + # NGINX License file + licenseJwtFile = j2_env.get_template(NcgConfig.config['templates']['license']).render( + nginxconf={'license': v5_2.MiscUtils.getDictKey(d, 'output.license')}) + + # Base64-encoded license file (/etc/nginx/license.jwt) + b64licenseJwtFile = str(base64.urlsafe_b64encode(licenseJwtFile.encode("utf-8")), "utf-8") + + # Base64-encoded NGINX mime.types (/etc/nginx/mime.types) + f = open(NcgConfig.config['templates']['root_dir'] + '/' + apiversion + '/' + NcgConfig.config['templates'][ + 'mimetypes'], 'r') + nginxMimeTypes = f.read() + f.close() + + b64NginxMimeTypes = str(base64.urlsafe_b64encode(nginxMimeTypes.encode("utf-8")), "utf-8") + filesMimeType = {'contents': b64NginxMimeTypes, 'name': NcgConfig.config['nms']['config_dir'] + '/mime.types'} + auxFiles['files'].append(filesMimeType) + + # Base64-encoded NGINX HTTP service configuration + filesNginxMain = {'contents': b64NginxMain, 'name': NcgConfig.config['nms']['config_dir'] + '/nginx.conf'} + filesLicenseFile = {'contents': b64licenseJwtFile, 'name': NcgConfig.config['nms']['config_dir'] + '/license.jwt'} + filesHttpConf = {'contents': b64HttpConf, + 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ + 'staged_config_http_filename']} + filesStreamConf = {'contents': b64StreamConf, + 'name': NcgConfig.config['nms']['config_dir'] + '/' + NcgConfig.config['nms'][ + 'staged_config_stream_filename']} + + # Append config files to staged configuration + configFiles['files'].append(filesNginxMain) + configFiles['files'].append(filesLicenseFile) + configFiles['files'].append(filesHttpConf) + configFiles['files'].append(filesStreamConf) + + # Staged config + baseStagedConfig = {'auxFiles': auxFiles, 'configFiles': configFiles} + stagedConfig = {'auxFiles': auxFiles, 'configFiles': configFiles, + 'updateTime': datetime.utcnow().isoformat()[:-3] + 'Z', + 'ignoreConflict': True, 'validateConfig': False} + + currentBaseStagedConfig = NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}').decode( + 'utf-8') if NcgRedis.redis.get(f'ncg.basestagedconfig.{configUid}') else None + newBaseStagedConfig = json.dumps(baseStagedConfig) + + if currentBaseStagedConfig is not None and newBaseStagedConfig == currentBaseStagedConfig: + print(f'Declaration [{configUid}] not changed') + return {"status_code": 200, + "message": {"status_code": 200, "message": {"code": 200, "content": "no changes"}}} + else: + # Configuration objects have changed, publish to NIM needed + print( + f'Declaration [{configUid}] changed, publishing' if configUid else f'New declaration created, publishing') + + # Get the instance group id + igUid = v5_2.NIMUtils.getNIMInstanceGroupUid(nmsUrl=nmsUrl, nmsUsername=nmsUsername, + nmsPassword=nmsPassword, instanceGroupName=nmsInstanceGroup) + + # Invalid instance group + if igUid is None: + return {"status_code": 404, + "message": {"status_code": 404, "message": {"code": 404, + "content": f"instance group {nmsInstanceGroup} not found"}}, + "headers": {'Content-Type': 'application/json'}} + + ### NGINX App Protect policies support - commits policies to control plane + + # Check NGINX App Protect WAF policies configuration sanity + status, description = v5_2.NAPUtils.checkDeclarationPolicies(d) + + if status != 200: + return {"status_code": 422, + "message": {"status_code": status, "message": {"code": status, "content": description}}, + "headers": {'Content-Type': 'application/json'}} + + # Provision NGINX App Protect WAF policies to NGINX Instance Manager + provisionedNapPolicies, activePolicyUids = v5_2.NAPUtils.provisionPolicies( + nmsUrl=nmsUrl, nmsUsername=nmsUsername, nmsPassword=nmsPassword, declaration=d) + + ### / NGINX App Protect policies support + + ### Publish staged config to instance group + r = requests.post(url=nmsUrl + f"/api/platform/v1/instance-groups/{igUid}/config", + data=json.dumps(stagedConfig), + headers={'Content-Type': 'application/json'}, + auth=(nmsUsername, nmsPassword), + verify=False) + + if r.status_code != 202: + # Configuration push failed + return {"status_code": r.status_code, + "message": {"status_code": r.status_code, "message": r.text}, + "headers": {'Content-Type': 'application/json'}} + + # Fetch the deployment status + publishResponse = json.loads(r.text) + + # Wait for either NIM success or failure after pushing a staged config + isPending = True + while isPending: + time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) + deploymentCheck = requests.get(url=nmsUrl + publishResponse['links']['rel'], + auth=(nmsUsername, nmsPassword), + verify=False) + + checkJson = json.loads(deploymentCheck.text) + + if not checkJson['details']['pending']: + isPending = False + + if len(checkJson['details']['failure']) > 0: + # Staged config publish to NIM failed + jsonResponse = checkJson['details']['failure'][0] + deploymentCheck.status_code = 422 + else: + # Staged config publish to NIM succeeded + jsonResponse = json.loads(deploymentCheck.text) + + # if nmsSynctime > 0 and runfromautosync == False: + if runfromautosync == False: + # No configuration is found, generate one + configUid = str(v5_2.MiscUtils.getuniqueid()) + + # Stores the staged config to redis + # Redis keys: + # ncg.declaration.[configUid] = original config declaration + # ncg.declarationrendered.[configUid] = original config declaration - rendered + # ncg.basestagedconfig.[configUid] = base staged configuration + # ncg.apiversion.[configUid] = ncg API version + # ncg.status.[configUid] = latest status + + NcgRedis.redis.set(f'ncg.declaration.{configUid}', pickle.dumps(declaration)) + NcgRedis.redis.set(f'ncg.declarationrendered.{configUid}', json.dumps(d)) + NcgRedis.redis.set(f'ncg.basestagedconfig.{configUid}', json.dumps(baseStagedConfig)) + NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) + + # Makes NGINX App Protect policies active + doWeHavePolicies = v5_2.NAPUtils.makePolicyActive(nmsUrl=nmsUrl, nmsUsername=nmsUsername, + nmsPassword=nmsPassword, + activePolicyUids=activePolicyUids, + instanceGroupUid=igUid) + + if doWeHavePolicies: + # Clean up NGINX App Protect WAF policies not used anymore + # and not defined in the declaration just pushed + time.sleep(NcgConfig.config['nms']['staged_config_publish_waittime']) + v5_2.NAPUtils.cleanPolicyLeftovers(nmsUrl=nmsUrl, nmsUsername=nmsUsername, + nmsPassword=nmsPassword, + currentPolicies=provisionedNapPolicies) + + # If deploying a new configuration in GitOps mode start autosync + if nmsSynctime == 0: + NcgRedis.declarationsList[configUid] = "static" + elif not runfromautosync: + # GitOps autosync + print(f'Starting autosync for configUid {configUid} every {nmsSynctime} seconds') + + job = schedule.every(nmsSynctime).seconds.do(lambda: V5_2_CreateConfig.configautosync(configUid)) + # Keep track of GitOps configs, key is the threaded job + NcgRedis.declarationsList[configUid] = job + + NcgRedis.redis.set(f'ncg.apiversion.{configUid}', apiversion) + + responseContent = {'code': deploymentCheck.status_code, 'content': jsonResponse, 'configUid': configUid} + + # Configuration push completed, update redis keys + if configUid != "": + NcgRedis.redis.set('ncg.status.' + configUid, json.dumps(responseContent)) + + # if nmsSynctime > 0: + # Updates status, declaration and basestagedconfig in redis + NcgRedis.redis.set('ncg.declaration.' + configUid, pickle.dumps(declaration)) + NcgRedis.redis.set('ncg.declarationrendered.' + configUid, json.dumps(d)) + NcgRedis.redis.set('ncg.basestagedconfig.' + configUid, json.dumps(baseStagedConfig)) + + return {"status_code": deploymentCheck.status_code, + "message": {"status_code": deploymentCheck.status_code, + "message": responseContent}, + "headers": {'Content-Type': 'application/json'} + } \ No newline at end of file diff --git a/src/v4_2/OpenAPIParser.py b/src/v5_2/OpenAPIParser.py similarity index 95% rename from src/v4_2/OpenAPIParser.py rename to src/v5_2/OpenAPIParser.py index 0e4e355..6097b07 100644 --- a/src/v4_2/OpenAPIParser.py +++ b/src/v5_2/OpenAPIParser.py @@ -54,7 +54,6 @@ def paths(self): methodInfo = self.openAPISchema['paths'][path][method] if method.upper() in self.httpMethods: - #print(f" - {method} - {methodInfo['description'] if 'description' in methodInfo else ''}") self.m = {} self.m['method'] = method self.m['details'] = {} diff --git a/templates/v4.2/configmap.tmpl b/templates/v4.2/configmap.tmpl deleted file mode 100644 index 29c3973..0000000 --- a/templates/v4.2/configmap.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ name }} - {% if namespace -%} - namespace: {{ namespace }} - {% endif %} - -data: - {{ filename }}: |- -{% filter indent(width = 4) %} - {{ nginxconfig }} -{% endfilter %} \ No newline at end of file diff --git a/templates/v4.2/apigateway.tmpl b/templates/v5.2/apigateway.tmpl similarity index 94% rename from templates/v4.2/apigateway.tmpl rename to templates/v5.2/apigateway.tmpl index 292c814..512a0bf 100644 --- a/templates/v4.2/apigateway.tmpl +++ b/templates/v5.2/apigateway.tmpl @@ -18,6 +18,10 @@ # Strip base URI: {{ declaration.location.apigateway.api_gateway.strip_uri }} # Destination server: {{ destination_server }} +{% for v in enabledVisibility %} +include "{{ ncgconfig.nms.visibility_dir }}{{ declaration.location.uri }}-{{ v }}-server.conf"; +{% endfor %} + {% if declaration.paths -%} {% for path in declaration.paths %} location {% if '{' not in path.path %}={% else %}~{% endif %} {{ declaration.location.uri }}{{ path.path | regex_replace('{(.*?)}','(.*)') }} { @@ -130,9 +134,11 @@ location {% if '{' not in path.path %}={% else %}~{% endif %} {{ declaration.loc {% endfor %} {% if declaration.location.apigateway.developer_portal.enabled == True -%} -location = {{ declaration.location.uri }}{{ declaration.location.apigateway.developer_portal.uri }} { + {% if declaration.location.apigateway.developer_portal.type.lower() == "redocly" %} +location = {{ declaration.location.uri }}{{ declaration.location.apigateway.developer_portal.redocly.uri }} { rewrite ^{{ declaration.location.uri }}/(.*)$ /$1 break; root {{ ncgconfig.nms.devportal_dir }}; } + {% endif %} {% endif %} -{% endif %} +{% endif %} \ No newline at end of file diff --git a/templates/v4.2/authn/client/jwks.tmpl b/templates/v5.2/authn/client/jwks.tmpl similarity index 100% rename from templates/v4.2/authn/client/jwks.tmpl rename to templates/v5.2/authn/client/jwks.tmpl diff --git a/templates/v4.2/authn/client/jwt.tmpl b/templates/v5.2/authn/client/jwt.tmpl similarity index 100% rename from templates/v4.2/authn/client/jwt.tmpl rename to templates/v5.2/authn/client/jwt.tmpl diff --git a/templates/v4.2/authn/client/mtls.tmpl b/templates/v5.2/authn/client/mtls.tmpl similarity index 100% rename from templates/v4.2/authn/client/mtls.tmpl rename to templates/v5.2/authn/client/mtls.tmpl diff --git a/templates/v4.2/authn/server/mtls.tmpl b/templates/v5.2/authn/server/mtls.tmpl similarity index 100% rename from templates/v4.2/authn/server/mtls.tmpl rename to templates/v5.2/authn/server/mtls.tmpl diff --git a/templates/v4.2/authn/server/token.tmpl b/templates/v5.2/authn/server/token.tmpl similarity index 100% rename from templates/v4.2/authn/server/token.tmpl rename to templates/v5.2/authn/server/token.tmpl diff --git a/templates/v4.2/authz/client/jwt-authz-map.tmpl b/templates/v5.2/authz/client/jwt-authz-map.tmpl similarity index 100% rename from templates/v4.2/authz/client/jwt-authz-map.tmpl rename to templates/v5.2/authz/client/jwt-authz-map.tmpl diff --git a/templates/v4.2/authz/client/jwt.tmpl b/templates/v5.2/authz/client/jwt.tmpl similarity index 100% rename from templates/v4.2/authz/client/jwt.tmpl rename to templates/v5.2/authz/client/jwt.tmpl diff --git a/templates/v5.2/devportal/backstage.tmpl b/templates/v5.2/devportal/backstage.tmpl new file mode 100644 index 0000000..9482f71 --- /dev/null +++ b/templates/v5.2/devportal/backstage.tmpl @@ -0,0 +1,17 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: {{ declaration.name }} + annotations: + github.com/project-slug: backstage/backstage + backstage.io/techdocs-ref: dir:. + lighthouse.com/website-url: https://backstage.io +spec: + type: openapi + lifecycle: {{ declaration.lifecycle }} + owner: {{ declaration.owner }} + system: {{ declaration.system }} + definition: | +{% filter indent(width=4) %} + {{ openAPISchema }} +{% endfilter %} \ No newline at end of file diff --git a/templates/v4.2/http.tmpl b/templates/v5.2/http.tmpl similarity index 93% rename from templates/v4.2/http.tmpl rename to templates/v5.2/http.tmpl index e62ef0e..5bcc643 100644 --- a/templates/v4.2/http.tmpl +++ b/templates/v5.2/http.tmpl @@ -49,36 +49,27 @@ include "{{ ncgconfig.nms.authz_client_dir }}/{{ authzprofile.name | replace(" " {# --- Upstreams section --- #} +# Upstreams {% if declaration.upstreams %} {% for u in declaration.upstreams %} {% if u.name %} -{% if u.origin %} -upstream {{ u.name }} { - zone {{ u.name }} 64k; - {% for o in u.origin -%} - server {{ o.server }}{% if o.weight %} weight={{ o.weight }}{% endif %}{% if o.max_fails %} max_fails={{ o.max_fails }}{% endif %}{% if o.fail_timeout %} fail_timeout={{ o.fail_timeout }}{% endif %}{% if o.max_conns %} max_conns={{ o.max_conns }}{% endif %}{% if o.slow_start %} slow_start={{ o.slow_start }}{% endif %}{% if o.backup and o.backup == True %} backup{% endif %}; - {% endfor %} - - {% if u.sticky and u.sticky.cookie and u.sticky.expires and u.sticky.domain and u.sticky.path -%} - sticky cookie {{ u.sticky.cookie }}{% if u.sticky.expires %} expires={{ u.sticky.expires }}{% endif %}{% if u.sticky.domain %} domain={{ u.sticky.domain }}{% endif %}{% if u.sticky.path %} path={{ u.sticky.path }}{% endif %}; - {% endif -%} - - {% if u.snippet and u.snippet.content %}{{ u.snippet.content | b64decode }}{% endif %} - -} -{% endif %} +include "{{ ncgconfig.nms.upstream_http_dir }}/{{ u.name | replace(' ', '_') }}.conf"; {% endif %} {% endfor %} {% endif %} {# --- Rate limit section --- #} - +# Rate limiting zones {% if declaration.rate_limit %} {% for rl in declaration.rate_limit %} limit_req_zone {{ rl.key }} zone={{ rl.name }}:{{ rl.size }} rate={{ rl.rate }}; {% endfor %} {% endif %} +{# --- Visibility integration section --- #} +# Visibility integrations +include "{{ ncgconfig.nms.visibility_dir }}/*-http.conf"; + {# --- Server section for NGINX Plus API --- #} {% if declaration.nginx_plus_api %} @@ -169,12 +160,12 @@ server { {% if s.names -%} server_name{% for svrname in s.names %} {{ svrname }}{% endfor -%}; - status_zone {{ s.names[0] }}; + status_zone {{ s.names[0] | replace(" ", "_") }}; proxy_ssl_server_name on; - {% endif -%} + {% endif %} {% if s.resolver -%} - resolver {{ s.resolver }}; + include "{{ ncgconfig.nms.resolver_dir }}/{{ s.resolver | replace(" ", "_") }}.conf"; {% endif -%} {# --- Server NGINX App Protect WAF section start --- #} diff --git a/templates/v4.2/logformat.tmpl b/templates/v5.2/logformat.tmpl similarity index 100% rename from templates/v4.2/logformat.tmpl rename to templates/v5.2/logformat.tmpl diff --git a/templates/v5.2/misc/resolver.tmpl b/templates/v5.2/misc/resolver.tmpl new file mode 100644 index 0000000..963bc3c --- /dev/null +++ b/templates/v5.2/misc/resolver.tmpl @@ -0,0 +1,4 @@ +# DNS resolver template + +resolver {{ resolverprofile.address }}{% if resolverprofile.valid %}valid={{ resolverprofile.valid }}{% endif %} ipv4={% if resolverprofile.ipv4 == True %}on{% else %}off{% endif %} ipv6={% if resolverprofile.ipv6 == True %}on{% else %}off{% endif %}; +{% if resolverprofile.timeout %}resolver_timeout {{ resolverprofile.timeout }}{% endif %}; \ No newline at end of file diff --git a/templates/v5.2/misc/upstream-http.tmpl b/templates/v5.2/misc/upstream-http.tmpl new file mode 100644 index 0000000..5c82a66 --- /dev/null +++ b/templates/v5.2/misc/upstream-http.tmpl @@ -0,0 +1,23 @@ +# HTTP upstream template + +{% if u.name %} +{% if u.origin %} +upstream {{ u.name }} { + zone {{ u.name }} 64k; + {% for o in u.origin -%} + server {{ o.server }}{% if o.weight %} weight={{ o.weight }}{% endif %}{% if o.max_fails %} max_fails={{ o.max_fails }}{% endif %}{% if o.fail_timeout %} fail_timeout={{ o.fail_timeout }}{% endif %}{% if o.max_conns %} max_conns={{ o.max_conns }}{% endif %}{% if o.slow_start %} slow_start={{ o.slow_start }}{% endif %}{% if o.backup and o.backup == True %} backup{% endif %}; + {% endfor %} + + {% if u.sticky and u.sticky.cookie and u.sticky.expires and u.sticky.domain and u.sticky.path -%} + sticky cookie {{ u.sticky.cookie }}{% if u.sticky.expires %} expires={{ u.sticky.expires }}{% endif %}{% if u.sticky.domain %} domain={{ u.sticky.domain }}{% endif %}{% if u.sticky.path %} path={{ u.sticky.path }}{% endif %}; + {% endif -%} + + {% if u.resolver -%} + include "{{ ncgconfig.nms.resolver_dir }}/{{ u.resolver | replace(" ", "_") }}.conf"; + {% endif -%} + + {% if u.snippet and u.snippet.content %}{{ u.snippet.content | b64decode }}{% endif %} + +} +{% endif %} +{% endif %} \ No newline at end of file diff --git a/templates/v5.2/misc/upstream-stream.tmpl b/templates/v5.2/misc/upstream-stream.tmpl new file mode 100644 index 0000000..2e686af --- /dev/null +++ b/templates/v5.2/misc/upstream-stream.tmpl @@ -0,0 +1,19 @@ +# Stream upstream template + +{% if u.name %} +{% if u.origin %} +upstream {{ u.name }} { + zone {{ u.name }} 64k; + {% for o in u.origin -%} + server {{ o.server }}{% if o.weight %} weight={{ o.weight }}{% endif %}{% if o.max_fails %} max_fails={{ o.max_fails }}{% endif %}{% if o.fail_timeout %} fail_timeout={{ o.fail_timeout }}{% endif %}{% if o.max_conns %} max_conns={{ o.max_conns }}{% endif %}{% if o.slow_start %} slow_start={{ o.slow_start }}{% endif %}{% if o.backup and o.backup == True %} backup{% endif %}; + {% endfor %} + + {% if u.snippet and u.snippet.content %}{{ u.snippet.content }}{% endif %} + + {% if u.resolver -%} + include "{{ ncgconfig.nms.resolver_dir }}/{{ u.resolver | replace(" ", "_") }}.conf"; + {% endif %} + +} +{% endif %} +{% endif %} \ No newline at end of file diff --git a/templates/v5.2/nginx-conf/license-key.tmpl b/templates/v5.2/nginx-conf/license-key.tmpl new file mode 100644 index 0000000..f729d84 --- /dev/null +++ b/templates/v5.2/nginx-conf/license-key.tmpl @@ -0,0 +1 @@ +{{ nginxconf.license.token }} \ No newline at end of file diff --git a/templates/v4.2/nginx-conf/mime.types b/templates/v5.2/nginx-conf/mime.types similarity index 100% rename from templates/v4.2/nginx-conf/mime.types rename to templates/v5.2/nginx-conf/mime.types diff --git a/templates/v4.2/nginx-conf/nginx.conf b/templates/v5.2/nginx-conf/nginx.conf similarity index 58% rename from templates/v4.2/nginx-conf/nginx.conf rename to templates/v5.2/nginx-conf/nginx.conf index 6ee69c9..32c79f3 100644 --- a/templates/v4.2/nginx-conf/nginx.conf +++ b/templates/v5.2/nginx-conf/nginx.conf @@ -29,7 +29,6 @@ http { include /etc/nginx/conf.d/*.conf; } - # TCP/UDP proxy and load balancing block stream { log_format stream-main '$remote_addr [$time_local] ' @@ -37,4 +36,22 @@ stream { '$session_time "$ssl_preread_server_name"'; #access_log /dev/stdout stream-main; include /etc/nginx/stream-conf.d/*.conf; -} \ No newline at end of file +} + +{% if nginxconf.license %} +# NGINX R33+ license +mgmt { + # Default reporting sent to product.connect.nginx.com + usage_report endpoint={{ nginxconf.license.endpoint }}; + license_token /etc/nginx/license.jwt; + + # Set to 'off' to begin the 180-day reporting enforcement grace period. + # Reporting must begin or resume before the end of the grace period + # to ensure continued operation. + enforce_initial_report {% if nginxconf.license.grace_period == False %}on{% else %}off{% endif %}; + + # Set to 'off' to trust all SSL certificates (not recommended). + # Useful for reporting to NGINX Instance Manager without a local PKI. + ssl_verify {% if nginxconf.license.ssl_verify == True %}on{% else %}off{% endif %}; +} +{% endif %} \ No newline at end of file diff --git a/templates/v4.2/stream.tmpl b/templates/v5.2/stream.tmpl similarity index 69% rename from templates/v4.2/stream.tmpl rename to templates/v5.2/stream.tmpl index 3ae64f0..d5628c2 100644 --- a/templates/v4.2/stream.tmpl +++ b/templates/v5.2/stream.tmpl @@ -1,26 +1,14 @@ # NGINX configuration file - Stream servers - generated by https://github.com/f5devcentral/NGINX-Declarative-API {# --- Upstreams section --- #} - {% if declaration.upstreams %} {% for u in declaration.upstreams %} {% if u.name %} -{% if u.origin %} -upstream {{ u.name }} { - zone {{ u.name }} 64k; - {% for o in u.origin -%} - server {{ o.server }}{% if o.weight %} weight={{ o.weight }}{% endif %}{% if o.max_fails %} max_fails={{ o.max_fails }}{% endif %}{% if o.fail_timeout %} fail_timeout={{ o.fail_timeout }}{% endif %}{% if o.max_conns %} max_conns={{ o.max_conns }}{% endif %}{% if o.slow_start %} slow_start={{ o.slow_start }}{% endif %}{% if o.backup and o.backup == True %} backup{% endif %}; - {% endfor %} - - {% if u.snippet and u.snippet.content %}{{ u.snippet.content }}{% endif %} - -} -{% endif %} +include "{{ ncgconfig.nms.upstream_stream_dir }}/{{ u.name | replace(' ', '_') }}.conf"; {% endif %} {% endfor %} {% endif %} - {# --- Stream server section --- #} {% for s in declaration.servers %} @@ -29,10 +17,13 @@ upstream {{ u.name }} { server { listen {{ s.listen.address }}{% if s.listen.protocol == "udp" %} {{ s.listen.protocol }}{% endif %}; - status_zone {{ s.name }}; + status_zone {{ s.name | replace(" ", "_") }}; {% endif -%} {% endif -%} + {% if s.resolver -%} + include "{{ ncgconfig.nms.resolver_dir }}/{{ s.resolver | replace(" ", "_") }}.conf"; + {% endif -%} {# --- TLS section --- #} {%- if s.listen.tls -%} diff --git a/templates/v5.2/visibility/moesif/http.tmpl b/templates/v5.2/visibility/moesif/http.tmpl new file mode 100644 index 0000000..ccf38e2 --- /dev/null +++ b/templates/v5.2/visibility/moesif/http.tmpl @@ -0,0 +1,14 @@ +# Moesif integration - https://www.moesif.com/docs/server-integration/nginx-openresty/ +# URI: {{ loc.uri }} +# application ID: {{ vis.moesif.application_id }} + +lua_shared_dict moesif_conf 5m; + +init_by_lua_block { + local config = ngx.shared.moesif_conf; + config:set("application_id", "{{ vis.moesif.application_id }}") +} + +lua_package_cpath ";;${prefix}?.so;${prefix}src/?.so;/usr/share/lua/5.1/lua/resty/moesif/?.so;/usr/share/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;/usr/lib/lua/5.1/?.so;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.so;/usr/local/share/lua/5.1/resty/moesif/?.so;{{ vis.moesif.plugin_path }}/?.so"; +lua_package_path ";;${prefix}?.lua;${prefix}src/?.lua;/usr/share/lua/5.1/lua/resty/moesif/?.lua;/usr/share/lua/5.1/?.lua;/usr/lib64/lua/5.1/?.lua;/usr/lib/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/lua/resty?.lua;/usr/local/share/lua/5.1/resty/moesif/?.lua;{{ vis.moesif.plugin_path }}/?.lua"; + diff --git a/templates/v5.2/visibility/moesif/server.tmpl b/templates/v5.2/visibility/moesif/server.tmpl new file mode 100644 index 0000000..51c58da --- /dev/null +++ b/templates/v5.2/visibility/moesif/server.tmpl @@ -0,0 +1,21 @@ +# Moesif integration - https://www.moesif.com/docs/server-integration/nginx-openresty/ +# URI: {{ loc.uri }} +# application ID: {{ vis.moesif.application_id }} + +# Define the variables Moesif requires +set $moesif_user_id nil; +set $moesif_company_id nil; +set $moesif_req_body nil; +set $moesif_res_body nil; + +# Optionally, set moesif_user_id and moesif_company_id such from a request header or NGINX var to identify customer +header_filter_by_lua_block { + ngx.var.moesif_user_id = ngx.req.get_headers()["X-User-Id"] + ngx.var.moesif_company_id = ngx.req.get_headers()["X-Company-Id"] +} + +# Add Moesif plugin +access_by_lua_file {{ vis.moesif.plugin_path }}/read_req_body.lua; +body_filter_by_lua_file {{ vis.moesif.plugin_path }}/read_res_body.lua; +log_by_lua_file {{ vis.moesif.plugin_path }}/send_event.lua; +