diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8550a806..5b2600c2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -76,8 +76,12 @@ test_node:4: - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash - export NVM_DIR="$HOME/.nvm" - source "$NVM_DIR/nvm.sh" - - nvm install 4 - - nvm install --latest-npm 12 + - n=0 + - until [ "$n" -ge 3 ]; do + - nvm install 4 && nvm install --latest-npm 12 && break + - n=$((n+1)) + - sleep 15 + - done - nvm use 12 - npm install --no-optional - npm install mocha@5.2.0 @@ -95,8 +99,12 @@ test_node:6: - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash - export NVM_DIR="$HOME/.nvm" - source "$NVM_DIR/nvm.sh" - - nvm install 6 - - nvm install --latest-npm 12 + - n=0 + - until [ "$n" -ge 3 ]; do + - nvm install 6 && nvm install --latest-npm 12 && break + - n=$((n+1)) + - sleep 15 + - done - nvm use 12 - npm ci --no-optional - npm install mocha@5.2.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index a67bfc20..ac39cf69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changelog Changes to this project are documented in this file. More detail and links can be found in the Declarative Onboarding [Document Revision History](https://clouddocs.f5.com/products/extensions/f5-declarative-onboarding/latest/revision-history.html). +## 1.40.0 +### Added +- AUTOTOOL-3931: ([GitHub Issue 656](https://github.com/F5Networks/f5-appsvcs-extension/issues/656)): Add WAF Settings configuration support on DO +- AUTOTOOL-3959: Add routeDomain property to RoutingPrefixList +- AUTOTOOL-1631: ([GitHub Issue 139](https://github.com/F5Networks/f5-declarative-onboarding/issues/139)): Configure username and password prompts + +### Fixed +- AUTOTOOL-3942: Fix documentation output from newlines in guiSecurityBannerText + +### Changed + +### Removed + ## 1.39.0 ### Added diff --git a/SUPPORT.md b/SUPPORT.md index 44d8d865..1c2b2033 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -14,8 +14,9 @@ Currently supported versions: | Software Version | Release Type | First Customer Ship | End of Support | |------------------|---------------|---------------------|-----------------| | DO 1.36.1 | LTS | 09-Mar-2023 | 09-Mar-2024 | -| DO 1.38.0 | Feature | 22-May-2023 | 22-Aug-2023 | | DO 1.39.0 | Feature | 24-Jul-2023 | 24-Oct-2023 | +| DO 1.39.1 | LTS | 12-Sep-2023 | 12-Sep-2024 | +| DO 1.40.0 | Feature | 12-Sep-2023 | 12-Dec-2023 | \* Fix for Allowed schema version @@ -66,6 +67,7 @@ Versions no longer supported: | DO 1.35.0 | Feature | 12-Jan-2023 | 12-Apr-2023 | | DO 1.36.0 | Feature | 09-Feb-2023 | 09-May-2023 | | DO 1.37.0 | Feature | 27-Mar-2022 | 27-Jun-2023 | +| DO 1.38.0 | Feature | 22-May-2023 | 22-Aug-2023 | \* Fix for updated Docker Container packaging only diff --git a/docs/composing-a-declaration.rst b/docs/composing-a-declaration.rst index ed832c35..1c92cd43 100644 --- a/docs/composing-a-declaration.rst +++ b/docs/composing-a-declaration.rst @@ -164,7 +164,7 @@ System class ```````````` The next lines of the declaration set the system-level options. This includes inactivity timeouts for CLI and Console sessions, and the ability to disable the phonehome property (see the table for details) in BIG-IP DO 1.10.0 and later. -For more information, see |systemclass| in the Schema Reference. Also see :ref:`The System Class example` for an example declaration. +For more information and new properties, see |systemclass| in the Schema Reference. Also see :ref:`The System Class example` for an example declaration. .. IMPORTANT:: If you set a hostname in the Common class, you cannot use the hostname property in the System class. We recommend using the System class for hostname diff --git a/docs/conf.py b/docs/conf.py index 635b235f..b3681f97 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -85,7 +85,7 @@ # The short X.Y version. version = u'' # The full version, including alpha/beta/rc tags. -release = u'1.39.0' +release = u'1.40.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/declarations/miscellaneous.rst b/docs/declarations/miscellaneous.rst index 46206f09..babcf140 100644 --- a/docs/declarations/miscellaneous.rst +++ b/docs/declarations/miscellaneous.rst @@ -38,14 +38,16 @@ BIG-IP DO 1.13 introduced the ability to disable the automatic update check feat BIG-IP DO 1.32 introduced the ability to modify the default security banner on the logon screen of the user interface using the **guiSecurityBanner** and **guiSecurityBannerText** properties. When **guiSecurityBanner** is set to **true**, you specify the text you want to display in the **guiSecurityBannerText** property. If you set **guiSecurityBanner** to **false**, the system presents an empty frame in the right portion of the login screen. +BIG-IP DO 1.40 introduced the ability to configure the username and password prompts (see the :ref:`specific example`) on this page. + In the following declaration, we show only the System class (including autoCheck introduced in 1.13, and the GUI security banner options in 1.32). You can use this class as a part of a larger BIG-IP Declarative Onboarding declaration. -**Important**: If you try to use this declaration with a BIG-IP DO version prior to 1.32, it will fail. Either upgrade BIG-IP DO to 1.32, or remove the guiSecurityBanner lines (highlighted in yellow). +**Important**: If you try to use this declaration with a BIG-IP DO version prior to 1.40, it will fail. Either upgrade BIG-IP DO to 1.40, or remove the lines (highlighted in yellow) and the comma at the end of the previous line. .. literalinclude:: ../../examples/system.json :language: json - :emphasize-lines: 15, 16 + :emphasize-lines: 17, 18 :ref:`Back to top` @@ -200,12 +202,61 @@ See |license| in the Schema Reference and the :ref:`Composing a Declaration ` +| + +.. _asmdo: + +Configuring BIG-IP ASM options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. sidebar:: :fonticon:`fa fa-info-circle fa-lg` Version Notice: + + Support for configuring BIG-IP ASM options is available in BIG-IP DO v1.40 and later. + +In this example, we show how you can use BIG-IP DO to configure BIG-IP Application Security Manager (ASM) options in a declaration using DO 1.40 and later. This includes settings like anti-virus protection and advanced configuration such as setting system variables. For general information on F5 application security, see https://www.f5.com/solutions/web-app-and-api-protection. + +See |secwaf| in the Schema Reference for more information and DO usage. + + +.. literalinclude:: ../../examples/securityWaf.json + :language: json + +:ref:`Back to top` + + +| + +.. _unpw: + +Configuring username and password prompts +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. sidebar:: :fonticon:`fa fa-info-circle fa-lg` Version Notice: + + Support for configuring username and password prompts is available in BIG-IP DO v1.40 and later. + +In this example, we show how BIG-IP DO can configure unique values for the BIG-IP username and password prompts. This means you can specify the text to present above the user name and password fields on the BIG-IP system login screen. + +You set these values as a part of the System class using the new properties **usernamePrompt** and **passwordPrompt**. + +See |sysclass| in the Schema Reference for more information and DO usage. + +.. IMPORTANT:: If you attempt to use the following declaration on a version prior to 1.40, it will fail. You can either upgrade BIG-IP DO, or remove lines 17 and 18 (and the comma at the end of line 16). + + +.. literalinclude:: ../../examples/system.json + :language: json + +:ref:`Back to top` + | .. |br| raw:: html
+.. |secwaf| raw:: html + + SecurityWaf + .. |rddoc| raw:: html Route Domain documentation @@ -218,6 +269,10 @@ See |license| in the Schema Reference and the :ref:`Composing a Declaration Monitoring BIG-IP System Traffic with SNMP +.. |sysclass| raw:: html + + System Class + .. |license| raw:: html License Class diff --git a/docs/revision-history.rst b/docs/revision-history.rst index 6c1a8a94..22be2494 100644 --- a/docs/revision-history.rst +++ b/docs/revision-history.rst @@ -11,6 +11,14 @@ Document Revision History - Description - Date + * - 1.40 + - Updated the documentation for Declarative Onboarding v1.40.0. This release contains the following changes: |br| * Added support for configuring BIG-IP ASM options in a declaration (see :ref:`AS3 options `), `GitHub Issue 656 `_ |br| * Support for configuring username and password prompts (see :ref:`Configuring username and password prompts`) |br| |br| Issues Resolved: |br| * Fix documentation output in the Schema Reference for the |system|. + - 9-12-23 + + * - 1.39 + - Updated the documentation for Declarative Onboarding v1.39.0. This release contains the following issues resolved: |br| * Failure to configure BIG-IP when built-in admin account is disabled |br| * DeviceCertificate hangs on BIG-IQ with no error response to user |br| * Empty object defaults can cause upgrade failures |br| * Renamed the primary branch in the GitHub repository for DO **main** + - 7-24-23 + * - 1.38 - Updated the documentation for Declarative Onboarding v1.38.0. This release contains the following changes: |br| * Added support for revoking a license on a BIG-IP, allowing revoking and relicensing in a declaration (see :ref:`Revoke and relicense `) |br| * Added support for referencing a URL in the **sslCaCert** property of LDAP authentication (see :ref:`Referencing a URL in the sslCaCert property`) |br| |br| Issues Resolved: |br| * Added missing protocol values for **SnmpUser_authentication** and **SnmpUser_privacy** - 5-22-23 diff --git a/examples/bgp.json b/examples/bgp.json index 49ceedde..f9869dc3 100644 --- a/examples/bgp.json +++ b/examples/bgp.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.20.0", + "schemaVersion": "1.40.0", "class": "Device", "async": true, "Common": { @@ -20,7 +20,6 @@ "id": 102, "connectionLimit": 5432991, "flowEvictionPolicy": "default-eviction-policy", - "ipIntelligencePolicy": "ip-intelligence", "strict": false, "vlans": [ "exampleVlan" @@ -53,7 +52,8 @@ "prefix": "192.0.2.0/24", "prefixLengthRange": 30 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRoutingPrefixList2": { "class": "RoutingPrefixList", @@ -64,7 +64,8 @@ "prefix": "192.0.2.0/24", "prefixLengthRange": 25 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRouteMap1": { "class": "RouteMap", diff --git a/examples/routeMap.json b/examples/routeMap.json index 03258e50..41e00008 100644 --- a/examples/routeMap.json +++ b/examples/routeMap.json @@ -1,5 +1,5 @@ { - "schemaVersion": "1.19.0", + "schemaVersion": "1.40.0", "class": "Device", "async": true, "Common": { @@ -20,7 +20,6 @@ "id": 102, "connectionLimit": 5432991, "flowEvictionPolicy": "default-eviction-policy", - "ipIntelligencePolicy": "ip-intelligence", "strict": false, "vlans": [ "exampleVlan" @@ -44,7 +43,8 @@ "prefix": "2001:db8::/127", "prefixLengthRange": 128 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRoutingPrefixList2": { "class": "RoutingPrefixList", @@ -55,7 +55,8 @@ "prefix": "2001:db8::/64", "prefixLengthRange": 80 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRoutingPrefixList3": { "class": "RoutingPrefixList", @@ -66,7 +67,8 @@ "prefix": "192.0.2.0/24", "prefixLengthRange": 30 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRoutingPrefixList4": { "class": "RoutingPrefixList", @@ -77,7 +79,8 @@ "prefix": "192.0.2.1/24", "prefixLengthRange": 25 } - ] + ], + "routeDomain": "exampleRouteDomain" }, "exampleRouteMap": { "class": "RouteMap", diff --git a/examples/routingPrefixList.json b/examples/routingPrefixList.json index d6cf7410..72705e9b 100644 --- a/examples/routingPrefixList.json +++ b/examples/routingPrefixList.json @@ -1,10 +1,30 @@ { - "schemaVersion": "1.23.0", + "schemaVersion": "1.40.0", "class": "Device", "async": true, "Common": { "class": "Tenant", "hostname": "bigip.example.com", + "exampleVlan": { + "class": "VLAN", + "tag": 100, + "interfaces": [ + { + "name": "1.1", + "tagged": true + } + ] + }, + "exampleRouteDomain": { + "class": "RouteDomain", + "id": 102, + "connectionLimit": 5432991, + "flowEvictionPolicy": "default-eviction-policy", + "strict": false, + "vlans": [ + "exampleVlan" + ] + }, "exampleRoutingPrefixList1": { "class": "RoutingPrefixList", "entries": [ @@ -20,7 +40,8 @@ "prefix": "2001:db8::/64", "prefixLengthRange": "80:" } - ] + ], + "routeDomain": "0" }, "exampleRoutingPrefixList2": { "class": "RoutingPrefixList", @@ -37,7 +58,8 @@ "prefix": "192.0.2.1/24", "prefixLengthRange": "25:27" } - ] + ], + "routeDomain": "exampleRouteDomain" } } } diff --git a/examples/securityWaf.json b/examples/securityWaf.json new file mode 100644 index 00000000..bb182b21 --- /dev/null +++ b/examples/securityWaf.json @@ -0,0 +1,30 @@ +{ + "async": true, + "schemaVersion": "1.40.0", + "class": "Device", + "Common": { + "class": "Tenant", + "securityWaf": { + "class": "SecurityWaf", + "antiVirusProtection": { + "guaranteeEnforcementEnabled": true, + "hostname": "test.hostname", + "port": 123 + }, + "advancedSettings": [ + { + "name": "max_json_policy_size", + "value": 5000 + }, + { + "name": "send_content_events", + "value": 1 + }, + { + "name": "WhiteHatIP1", + "value": "192.0.2.10/8" + } + ] + } + } +} diff --git a/examples/system.json b/examples/system.json index 3975b37d..865856dc 100644 --- a/examples/system.json +++ b/examples/system.json @@ -13,7 +13,9 @@ "autoCheck": false, "autoPhonehome": true, "guiSecurityBanner": true, - "guiSecurityBannerText": "Authorized access only\n\nLogin on the left" + "guiSecurityBannerText": "Authorized access only\n\nLogin on the left", + "usernamePrompt": "Your username:", + "passwordPrompt": "Your password:" } } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 11464e27..db410d84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "f5-declarative-onboarding", - "version": "1.39.0-4", + "version": "1.40.0-8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -8,7 +8,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, + "devOptional": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -30,6 +30,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "devOptional": true, "requires": { "@babel/highlight": "^7.22.5" } @@ -38,13 +39,13 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", - "dev": true + "devOptional": true }, "@babel/core": { "version": "7.21.8", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", - "dev": true, + "devOptional": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.21.4", @@ -67,13 +68,13 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "devOptional": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true } } }, @@ -81,7 +82,7 @@ "version": "7.21.9", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.9.tgz", "integrity": "sha512-F3fZga2uv09wFdEjEQIJxXALXfz0+JaOb7SabvVMmjHxeVTuGW8wgE8Vp1Hd7O+zMTYtcfEISGRzPkeiaPPsvg==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.21.5", "@jridgewell/gen-mapping": "^0.3.2", @@ -93,6 +94,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "devOptional": true, "requires": { "@babel/types": "^7.22.5" } @@ -101,7 +103,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", - "dev": true, + "devOptional": true, "requires": { "@babel/compat-data": "^7.22.5", "@babel/helper-validator-option": "^7.22.5", @@ -111,17 +113,17 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz", - "integrity": "sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz", + "integrity": "sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -129,16 +131,25 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-member-expression-to-functions": "^7.22.5", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "semver": "^6.3.0" + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -146,12 +157,14 @@ "@babel/helper-environment-visitor": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==" + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "devOptional": true }, "@babel/helper-function-name": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "devOptional": true, "requires": { "@babel/template": "^7.22.5", "@babel/types": "^7.22.5" @@ -161,6 +174,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "devOptional": true, "requires": { "@babel/types": "^7.22.5" } @@ -178,6 +192,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "devOptional": true, "requires": { "@babel/types": "^7.22.5" } @@ -186,7 +201,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.5", @@ -211,27 +226,24 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true + "devOptional": true }, "@babel/helper-replace-supers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz", - "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", + "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-optimise-call-expression": "^7.22.5" } }, "@babel/helper-simple-access": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, + "devOptional": true, "requires": { "@babel/types": "^7.22.5" } @@ -249,6 +261,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "devOptional": true, "requires": { "@babel/types": "^7.22.5" } @@ -256,24 +269,26 @@ "@babel/helper-string-parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "devOptional": true }, "@babel/helper-validator-identifier": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "devOptional": true }, "@babel/helper-validator-option": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", - "dev": true + "devOptional": true }, "@babel/helpers": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz", "integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==", - "dev": true, + "devOptional": true, "requires": { "@babel/template": "^7.22.5", "@babel/traverse": "^7.22.5", @@ -284,6 +299,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "devOptional": true, "requires": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", @@ -294,6 +310,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, "requires": { "color-convert": "^1.9.0" } @@ -302,6 +319,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -312,6 +330,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, "requires": { "color-name": "1.1.3" } @@ -319,22 +338,26 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, "requires": { "has-flag": "^3.0.0" } @@ -345,7 +368,7 @@ "version": "7.21.9", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.9.tgz", "integrity": "sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==", - "dev": true + "devOptional": true }, "@babel/plugin-proposal-class-properties": { "version": "7.18.6", @@ -358,16 +381,27 @@ } }, "@babel/plugin-proposal-decorators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.5.tgz", - "integrity": "sha512-h8hlezQ4dl6ixodgXkH8lUfcD7x+WAuIqPUjwGoItynrXOAv4a4Tci1zA/qjzQjjcl0v3QpLdc2LM6ZACQuY7A==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.10.tgz", + "integrity": "sha512-KxN6TqZzcFi4uD3UifqXElBTBNLAEH1l3vzMQj6JwJZbL2sZlThxSViOKCYY+4Ah4V4JhQ95IVB7s/Y6SJSlMQ==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.10", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/plugin-syntax-decorators": "^7.22.5" + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.22.10" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + } } }, "@babel/plugin-proposal-private-methods": { @@ -381,9 +415,9 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.5.tgz", - "integrity": "sha512-avpUOBS7IU6al8MmF1XpAyj9QYeLPuSDJI5D4pVMSMdL7xQokKqJPYQC67RCT0aCTashUXPiGwMJ0DEXXCEmMA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz", + "integrity": "sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5" @@ -393,7 +427,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "dev": true, + "devOptional": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5" } @@ -419,43 +453,44 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz", - "integrity": "sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.10.tgz", + "integrity": "sha512-7++c8I/ymsDo4QQBAgbraXLzIM6jmfao11KgIBEYZRReWzNWH9NtNgJcyrZiXsOPh523FQm6LfpLyy/U5fn46A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.10", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.22.5" } }, "@babel/preset-typescript": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz", - "integrity": "sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", + "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/plugin-transform-modules-commonjs": "^7.21.5", - "@babel/plugin-transform-typescript": "^7.21.3" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.5", + "@babel/plugin-transform-typescript": "^7.22.5" } }, "@babel/runtime": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz", + "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==", "optional": true, "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" } }, "@babel/template": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "devOptional": true, "requires": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -465,7 +500,8 @@ "@babel/parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==" + "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "devOptional": true } } }, @@ -473,6 +509,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", + "devOptional": true, "requires": { "@babel/code-frame": "^7.22.5", "@babel/generator": "^7.22.5", @@ -490,6 +527,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "devOptional": true, "requires": { "@babel/types": "^7.22.5", "@jridgewell/gen-mapping": "^0.3.2", @@ -500,7 +538,8 @@ "@babel/parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==" + "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "devOptional": true } } }, @@ -508,6 +547,7 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "devOptional": true, "requires": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -515,18 +555,18 @@ } }, "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "optional": true, "requires": { - "@emotion/memoize": "0.7.4" + "@emotion/memoize": "^0.8.1" } }, "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", "optional": true }, "@emotion/stylis": { @@ -614,15 +654,15 @@ } }, "@exodus/schemasafe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.0.1.tgz", - "integrity": "sha512-PQdbF8dGd4LnbwBlcc4ML8RKYdplm+e9sUeWBTr4zgF13/Shiuov9XznvM4T8cb1CfyKK21yTUkuAIIh/DAH/g==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.2.3.tgz", + "integrity": "sha512-hmdFF4vVyvXosVdCCnZPCfrgwNPA79y3K5l0QzlKFcK5Qd3nkM9oGKcQYCTnTRWJXIV5SUMkkTFIEIdDFtxQPQ==", "optional": true }, "@f5devcentral/atg-shared-utilities": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@f5devcentral/atg-shared-utilities/-/atg-shared-utilities-0.7.0.tgz", - "integrity": "sha512-5XIjHk9yhIYwzmwZOjYqcqcaPMqI4MJKyHoM0NG7ouatyUWEC/JQ3P519+risx1EohCCs1M2z1yBuc+cBrnFmw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@f5devcentral/atg-shared-utilities/-/atg-shared-utilities-0.10.1.tgz", + "integrity": "sha512-lCZpDeoFkaJpzhGU7PLnrihhCQSaf11j3GKi0vB+30quewSWrtFkrYsOiq3RmO9FDNlqKcSIqKhgtDIjTwLwow==", "requires": { "big-integer": "^1.6.51", "error": "7.2.1", @@ -630,9 +670,9 @@ } }, "@f5devcentral/atg-shared-utilities-dev": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@f5devcentral/atg-shared-utilities-dev/-/atg-shared-utilities-dev-0.2.13.tgz", - "integrity": "sha512-EJ5sJoG8ysDBSb4hVxhtyMjdXbE1nOl0jxnRKBuJb6QHmcgrR75Vzvht1iBlxIU0tQO819odGNwCk2fir379MA==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@f5devcentral/atg-shared-utilities-dev/-/atg-shared-utilities-dev-0.2.14.tgz", + "integrity": "sha512-uEz5T6xByUf4MJszJAmm2tj+NWb0yZjayGU6wHsJTWa8Um2z3k8MZPXstmDPBQug2IOeQtGsKD2Q+5e2H9FK8Q==", "dev": true }, "@f5devcentral/atg-storage": { @@ -743,6 +783,40 @@ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -751,6 +825,62 @@ "requires": { "ansi-regex": "^6.0.1" } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } } } }, @@ -841,6 +971,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "devOptional": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -850,22 +981,26 @@ "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "devOptional": true }, "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "devOptional": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "devOptional": true }, "@jridgewell/trace-mapping": { "version": "0.3.18", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "devOptional": true, "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -874,7 +1009,8 @@ "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "devOptional": true } } }, @@ -884,6 +1020,12 @@ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "dev": true }, + "@ljharb/through": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.9.tgz", + "integrity": "sha512-yN599ZBuMPPK4tdoToLlvgJB4CLK8fGl7ntfy0Wn7U6ttNvHYurd81bfUiK/6sMkiIwm65R6ck4L6+Y3DfVbNQ==", + "dev": true + }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -904,33 +1046,59 @@ } }, "@redocly/cli": { - "version": "1.0.0-beta.128", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.0.0-beta.128.tgz", - "integrity": "sha512-+IDgJtPx9i31cV0FU1gG28fI9/LrV7KnCGmF/NK6GB5xbM7wb9MMp9ol8+j05t21/AY7iXAUmJtbQaCHBllkLw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.0.2.tgz", + "integrity": "sha512-IWuo5V2ZKSdvQMgNx05PHBlv1YvqJH3/nX52qslooEtqsvOaCUnZIm/aCd1zw2EW5Ub2+VLb51LqMt6mDF/9vQ==", "optional": true, "requires": { - "@redocly/openapi-core": "1.0.0-beta.128", + "@redocly/openapi-core": "1.0.2", "assert-node-version": "^1.0.3", "chokidar": "^3.5.1", "colorette": "^1.2.0", "glob": "^7.1.6", "glob-promise": "^3.4.0", "handlebars": "^4.7.6", - "mobx": "^6.3.2", + "mobx": "^6.0.4", "portfinder": "^1.0.26", - "react": "^17.0.1", - "react-dom": "^17.0.1", + "react": "^17.0.0", + "react-dom": "^17.0.0", "redoc": "~2.0.0", - "semver": "^7.5.1", + "semver": "^7.5.2", "simple-websocket": "^9.0.0", - "styled-components": "5.3.3", + "styled-components": "^5.1.1", "yargs": "17.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } } }, "@redocly/openapi-core": { - "version": "1.0.0-beta.128", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.0.0-beta.128.tgz", - "integrity": "sha512-3tubjnSOuC/1QQ8NnOFMTudA4pwbWnVJXB64JYNgiE99cTQS+90wehvQiV71XHQMC9/+rPvt4Ft7GXw75hFoNQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.0.2.tgz", + "integrity": "sha512-53dzhmG2bsi/8rcAAgBKk9ZLMR035VHgN7oSM3+BM4UAIoNBg6lMC/ChHSf9zO+GrX5qtuWVPqHhjjMti3SAlQ==", "optional": true, "requires": { "@redocly/ajv": "^8.11.0", @@ -982,34 +1150,35 @@ "dev": true }, "@stryker-mutator/api": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-7.0.2.tgz", - "integrity": "sha512-JGoMBMU8vZJPM0PA3gFiD7gqF9RKSlY7eHaAzbH6OtwerzAFb1NBj7Rsg2dvIyFnglxqNbFAYLdv4ZPJNNkRxQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/api/-/api-7.1.1.tgz", + "integrity": "sha512-LqCO/UbMxPmr26LbFHSgKpHh3sKROPwjhiQlB3p962u3Z424xHE6jdkt+1wdTNxM1ycCK+GpHeCo6iiXkEBipw==", "dev": true, "requires": { "mutation-testing-metrics": "2.0.1", "mutation-testing-report-schema": "2.0.1", - "tslib": "~2.5.0" + "tslib": "~2.6.0", + "typed-inject": "~4.0.0" } }, "@stryker-mutator/core": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-7.0.2.tgz", - "integrity": "sha512-noebN7Ir+xsTgJvC0aFfxVwKv6A/+HQwPdjJvIKGoL1NATqAZ+ELVw2neoH9HZE9AaYE26OW5h61KylFyRP5TQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/core/-/core-7.1.1.tgz", + "integrity": "sha512-E+SLgxfZwcx14sce72G+bTFDBN7at4QiRrBVTV8nXILShyAfvWSQu56Yu3VTsbAKJZAJO+LkNYbyO+ZtmsCwow==", "dev": true, "requires": { - "@stryker-mutator/api": "7.0.2", - "@stryker-mutator/instrumenter": "7.0.2", - "@stryker-mutator/util": "7.0.2", + "@stryker-mutator/api": "7.1.1", + "@stryker-mutator/instrumenter": "7.1.1", + "@stryker-mutator/util": "7.1.1", "ajv": "~8.12.0", - "chalk": "~5.2.0", - "commander": "~10.0.0", + "chalk": "~5.3.0", + "commander": "~11.0.0", "diff-match-patch": "1.0.5", "emoji-regex": "~10.2.1", "execa": "~7.1.0", "file-url": "~4.0.0", "get-port": "~7.0.0", - "glob": "~10.2.6", + "glob": "~10.3.0", "inquirer": "~9.2.0", "lodash.flatmap": "~4.5.0", "lodash.groupby": "~4.6.0", @@ -1024,7 +1193,7 @@ "semver": "^7.3.5", "source-map": "~0.7.3", "tree-kill": "~1.2.2", - "tslib": "2.5.3", + "tslib": "2.6.0", "typed-inject": "~4.0.0", "typed-rest-client": "~1.8.0" }, @@ -1042,9 +1211,9 @@ } }, "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", "dev": true }, "foreground-child": { @@ -1058,39 +1227,39 @@ } }, "glob": { - "version": "10.2.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.7.tgz", - "integrity": "sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==", + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", "dev": true, "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" } }, "minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, "signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true } } }, "@stryker-mutator/instrumenter": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-7.0.2.tgz", - "integrity": "sha512-jbj8v6leiJrYYztvg6oPlAAoNQANtuwedyOBZYPwrr7RPilc80zvnk21+26zhP4XHJRzikeNtDmxx/QHhATjRQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/instrumenter/-/instrumenter-7.1.1.tgz", + "integrity": "sha512-z1p7HMPvxWH/QVeanLpwt1B+LtwFRdd5GcR8Lx+REBAL8cAjzo8/DOYJ5BJp20ab7ZpbID8fPjIKr/P+Im/qGQ==", "dev": true, "requires": { "@babel/core": "~7.22.0", @@ -1099,52 +1268,219 @@ "@babel/plugin-proposal-class-properties": "~7.18.0", "@babel/plugin-proposal-decorators": "~7.22.0", "@babel/plugin-proposal-private-methods": "~7.18.0", - "@babel/preset-typescript": "~7.21.0", - "@stryker-mutator/api": "7.0.2", - "@stryker-mutator/util": "7.0.2", + "@babel/preset-typescript": "~7.22.0", + "@stryker-mutator/api": "7.1.1", + "@stryker-mutator/util": "7.1.1", "angular-html-parser": "~4.0.0", "weapon-regex": "~1.1.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", + "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.10", + "chalk": "^2.4.2" + } + }, + "@babel/compat-data": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "dev": true + }, "@babel/core": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", - "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", + "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.5", - "@babel/parser": "^7.22.5", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.10", + "@babel/parser": "^7.22.10", "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", + "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, "requires": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" } }, + "@babel/helper-compilation-targets": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", + "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helpers": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", + "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10" + } + }, + "@babel/highlight": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", + "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, "@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", + "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", + "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.10", + "@babel/types": "^7.22.10", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", + "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + } + }, + "caniuse-lite": { + "version": "1.0.30001521", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001521.tgz", + "integrity": "sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.496", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.496.tgz", + "integrity": "sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "json5": { @@ -1153,29 +1489,44 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, + "node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "@stryker-mutator/mocha-runner": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@stryker-mutator/mocha-runner/-/mocha-runner-7.0.2.tgz", - "integrity": "sha512-m/CkbhETp7Ah143SOTUTzk+7W2MvQtqeAayA+60BzEtlmUH3dA0LKUqaken0sZLy2NdijsaC92dXlIRbjTvl0g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/mocha-runner/-/mocha-runner-7.1.1.tgz", + "integrity": "sha512-IO37Efu3KN7A3gigIp/iI5d6bEMwFwb4ZhjUedtvxEcXxxfmcGvKKR4yan4a+lT1CXvZIZLzOM+oS2zc2hsprw==", "dev": true, "requires": { - "@stryker-mutator/api": "7.0.2", - "@stryker-mutator/util": "7.0.2", - "tslib": "~2.5.0" + "@stryker-mutator/api": "7.1.1", + "@stryker-mutator/util": "7.1.1", + "tslib": "~2.6.0" } }, "@stryker-mutator/util": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-7.0.2.tgz", - "integrity": "sha512-g58UI2fPkomPtyFcJIedrP0DwTGDqIH5xZ6QSfmU+/yHZ8tpbFdJl7ADLakASw+DSSP/G770uQND3zrctIaPDA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@stryker-mutator/util/-/util-7.1.1.tgz", + "integrity": "sha512-LIV7vVrC7dT04BDYZEYkYmetN7WQqD9xiQJRpkrYgACPGdu3eAAfk8UwRSoXAgMqAfZnYC2c+0BuliS8jDdBoQ==", "dev": true, "requires": { "lodash.flatmap": "~4.5.0" @@ -1194,7 +1545,8 @@ "@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "devOptional": true }, "@types/json5": { "version": "0.0.29", @@ -1209,9 +1561,9 @@ "optional": true }, "@types/node": { - "version": "14.18.48", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.48.tgz", - "integrity": "sha512-iL0PIMwejpmuVHgfibHpfDwOdsbmB50wr21X71VnF5d7SsBF7WK+ZvP/SCcFm7Iwb9iiYSap9rlrdhToNAWdxg==", + "version": "14.18.54", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz", + "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw==", "optional": true }, "@types/ssh2": { @@ -1241,7 +1593,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "aggregate-error": { "version": "3.1.0", @@ -1304,12 +1657,14 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "requires": { "color-convert": "^2.0.1" } @@ -1318,6 +1673,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1335,13 +1691,14 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "devOptional": true }, "array-buffer-byte-length": { "version": "1.0.0", @@ -1356,7 +1713,7 @@ "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, "array-includes": { @@ -1400,6 +1757,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "optional": true, "requires": { "safer-buffer": "~2.1.0" } @@ -1415,19 +1773,13 @@ }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "optional": true } } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -1448,53 +1800,30 @@ "lodash": "^4.17.14" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "babel-plugin-styled-components": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.3.tgz", - "integrity": "sha512-jBioLwBVHpOMU4NsueH/ADcHrjS0Y/WTpt2eGVmmuSFNEv2DF3XhcMncuZlbbjxQ4vzxg+yEr6E6TNjrIQbsJQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", "optional": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.21.4", - "babel-plugin-syntax-jsx": "^6.18.0", + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", "lodash": "^4.17.21", "picomatch": "^2.3.1" } }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", - "optional": true - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true }, "base64-js": { "version": "1.5.1", @@ -1505,7 +1834,8 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1518,7 +1848,8 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true }, "bl": { "version": "4.1.0", @@ -1535,6 +1866,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "devOptional": true, "requires": { "balanced-match": "^1.0.0" } @@ -1543,6 +1875,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, "requires": { "fill-range": "^7.0.1" } @@ -1557,7 +1890,7 @@ "version": "4.21.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz", "integrity": "sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==", - "dev": true, + "devOptional": true, "requires": { "caniuse-lite": "^1.0.30001489", "electron-to-chromium": "^1.4.411", @@ -1618,7 +1951,8 @@ "call-me-maybe": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "devOptional": true }, "callsites": { "version": "3.1.0", @@ -1642,13 +1976,7 @@ "version": "1.0.30001497", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001497.tgz", "integrity": "sha512-I4/duVK4wL6rAK/aKZl3HXB4g+lIZvaT4VLAn2rCgJ38jVLb0lv2Xug6QuqmxXFVRJMF74SPPWPJ/1Sdm3vCzw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "devOptional": true }, "chai": { "version": "4.3.7", @@ -1675,9 +2003,9 @@ } }, "chalk": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", - "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true }, "chardet": { @@ -1689,13 +2017,14 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1735,15 +2064,16 @@ "dev": true }, "cli-width": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", - "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "devOptional": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -1753,12 +2083,14 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1769,6 +2101,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1793,6 +2126,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "requires": { "color-name": "~1.1.4" } @@ -1800,7 +2134,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "colorette": { "version": "1.4.0", @@ -1814,15 +2149,6 @@ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -1831,13 +2157,14 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "devOptional": true }, "confusing-browser-globals": { "version": "1.0.11", @@ -1849,13 +2176,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "devOptional": true }, "cpu-features": { "version": "0.0.8", @@ -1900,15 +2221,6 @@ "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", "integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==" }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -1919,6 +2231,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "devOptional": true, "requires": { "ms": "2.1.2" } @@ -1997,12 +2310,6 @@ "object-keys": "^1.1.1" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -2025,9 +2332,9 @@ } }, "dompurify": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.5.tgz", - "integrity": "sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA==", + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz", + "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==", "optional": true }, "eastasianwidth": { @@ -2036,21 +2343,11 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "electron-to-chromium": { "version": "1.4.427", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz", "integrity": "sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==", - "dev": true + "devOptional": true }, "emoji-regex": { "version": "10.2.1", @@ -2164,12 +2461,13 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true }, "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "eslint": { @@ -2331,9 +2629,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -2432,9 +2730,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -2572,12 +2870,6 @@ "integrity": "sha512-OSaCdgF02srujDqJz1JWGpqk8Rq3uNYHLmtpBHJrZN3BvuMvzijJMqRVxZN1qLJtKVwjXhmOp+lfsRUqx8n54w==", "optional": true }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -2589,12 +2881,6 @@ "tmp": "^0.0.33" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, "eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -2613,7 +2899,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "fast-safe-stringify": { @@ -2630,6 +2916,14 @@ "requires": { "escape-string-regexp": "^5.0.0", "is-unicode-supported": "^1.2.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true + } } }, "file-entry-cache": { @@ -2651,6 +2945,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, "requires": { "to-regex-range": "^5.0.1" } @@ -2734,23 +3029,6 @@ "signal-exit": "^3.0.2" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -2771,7 +3049,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "devOptional": true }, "fsevents": { "version": "2.3.2", @@ -2800,7 +3079,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "functions-have-names": { @@ -2813,12 +3092,13 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "devOptional": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true }, "get-func-name": { "version": "2.0.0", @@ -2866,19 +3146,11 @@ "get-intrinsic": "^1.1.1" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "devOptional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2892,6 +3164,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "devOptional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2901,6 +3174,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "devOptional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2911,6 +3185,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, "requires": { "is-glob": "^4.0.1" } @@ -2927,7 +3202,8 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true }, "globalthis": { "version": "1.0.3", @@ -2954,13 +3230,13 @@ "dev": true }, "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "optional": true, "requires": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" @@ -2974,22 +3250,6 @@ } } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3090,14 +3350,6 @@ "optional": true, "requires": { "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "optional": true - } } }, "html-escaper": { @@ -3106,17 +3358,6 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "http2-client": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", @@ -3163,7 +3404,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "indent-string": { @@ -3175,7 +3416,8 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "devOptional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3184,19 +3426,21 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "devOptional": true }, "inquirer": { - "version": "9.2.7", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.7.tgz", - "integrity": "sha512-Bf52lnfvNxGPJPltiNO2tLBp3zC339KNlGMqOkW+dsvNikBhcVDK5kqU2lVX2FTPzuXUFX5WJDlsw//w3ZwoTw==", + "version": "9.2.10", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.10.tgz", + "integrity": "sha512-tVVNFIXU8qNHoULiazz612GFl+yqNfjMTbLuViNJE/d860Qxrd3NMrse8dm40VUQLOQeULvaQF8lpAhvysjeyA==", "dev": true, "requires": { + "@ljharb/through": "^2.3.9", "ansi-escapes": "^4.3.2", - "chalk": "^5.2.0", + "chalk": "^5.3.0", "cli-cursor": "^3.1.0", - "cli-width": "^4.0.0", - "external-editor": "^3.0.3", + "cli-width": "^4.1.0", + "external-editor": "^3.1.0", "figures": "^5.0.0", "lodash": "^4.17.21", "mute-stream": "1.0.0", @@ -3205,8 +3449,7 @@ "rxjs": "^7.8.1", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" + "wrap-ansi": "^6.2.0" }, "dependencies": { "emoji-regex": { @@ -3284,6 +3527,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, "requires": { "binary-extensions": "^2.0.0" } @@ -3325,17 +3569,20 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "devOptional": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, "requires": { "is-extglob": "^2.1.1" } @@ -3360,7 +3607,8 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true }, "is-number-object": { "version": "1.0.7", @@ -3436,7 +3684,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "is-unicode-supported": { @@ -3463,19 +3711,19 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -3505,9 +3753,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -3585,9 +3833,9 @@ } }, "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -3595,9 +3843,9 @@ } }, "jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.0.tgz", + "integrity": "sha512-uKmsITSsF4rUWQHzqaRUuyAir3fZfW3f202Ee34lz/gZCi970CPZwyQXLGNgWJvvZbvFyzeyGq0+4fcG/mBKZg==", "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", @@ -3639,26 +3887,23 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "devOptional": true }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "devOptional": true, "requires": { "argparse": "^2.0.1" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "devOptional": true }, "json-pointer": { "version": "0.6.2", @@ -3669,12 +3914,6 @@ "foreach": "^2.0.4" } }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, "json-schema-ref-parser": { "version": "9.0.9", "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", @@ -3687,18 +3926,19 @@ "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "devOptional": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "json5": { @@ -3719,18 +3959,6 @@ "graceful-fs": "^4.1.6" } }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -3770,7 +3998,7 @@ "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.groupby": { @@ -3794,7 +4022,7 @@ "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, "log-symbols": { @@ -3881,7 +4109,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "devOptional": true, "requires": { "yallist": "^3.0.2" } @@ -3896,14 +4124,16 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "devOptional": true, "requires": { "semver": "^6.0.0" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true } } }, @@ -3925,21 +4155,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, "mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -3958,12 +4173,13 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "devOptional": true }, "minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true }, "mkdirp": { @@ -3973,9 +4189,9 @@ "dev": true }, "mobx": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.9.0.tgz", - "integrity": "sha512-HdKewQEREEJgsWnErClfbFoVebze6rGazxFLU/XUyrII8dORfVszN1V0BMRnQSzcgsNNtkX8DHj3nC6cdWE9YQ==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.10.0.tgz", + "integrity": "sha512-WMbVpCMFtolbB8swQ5E2YRrU+Yu8iLozCVx3CdGjbBKlP7dFiCSuiG06uea3JCFN5DnvtAX7+G5Bp82e2xu0ww==", "optional": true }, "mobx-react": { @@ -3991,7 +4207,8 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-3.4.3.tgz", "integrity": "sha512-NkJREyFTSUXR772Qaai51BnE1voWx56LOL80xG7qkZr6vo8vEaLF3sz1JNUVh+rxmUzxYaqOhfuxTfqUh0FXUg==", - "optional": true + "optional": true, + "requires": {} }, "mocha": { "version": "10.2.0", @@ -4142,7 +4359,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "mutation-testing-elements": { "version": "2.0.1", @@ -4186,7 +4404,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "neo-async": { @@ -4255,17 +4473,17 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true } } }, "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", "optional": true, "requires": { "whatwg-url": "^5.0.0" @@ -4308,7 +4526,7 @@ "version": "2.0.12", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", - "dev": true + "devOptional": true }, "node-ssh": { "version": "13.1.0", @@ -4336,7 +4554,8 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true }, "npm-run-path": { "version": "5.1.0", @@ -4538,6 +4757,19 @@ "yaml": "^1.10.0" } }, + "oas-resolver": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", + "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", + "optional": true, + "requires": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + } + }, "oas-schema-walker": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", @@ -4558,29 +4790,8 @@ "reftools": "^1.1.9", "should": "^13.2.1", "yaml": "^1.10.0" - }, - "dependencies": { - "oas-resolver": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", - "optional": true, - "requires": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - } - } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4646,7 +4857,8 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "devOptional": true, "requires": { "wrappy": "1" } @@ -4809,7 +5021,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "devOptional": true }, "path-key": { "version": "3.1.1", @@ -4824,19 +5037,19 @@ "dev": true }, "path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true } } @@ -4862,22 +5075,17 @@ "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==", "optional": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "devOptional": true }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true }, "pkg-dir": { "version": "4.2.0", @@ -5021,14 +5229,6 @@ "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "optional": true - } } }, "propagate": { @@ -5037,12 +5237,6 @@ "integrity": "sha512-T/rqCJJaIPYObiLSmaDsIf4PGA7y+pkgYFHmwoXQyOHiDDSO1YCxcztNiRBmV4EZha4QIbID3vQIHkqKu5k0Xg==", "dev": true }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -5072,6 +5266,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "devOptional": true, "requires": { "safe-buffer": "^5.1.0" } @@ -5097,6 +5292,12 @@ "scheduler": "^0.20.2" } }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "optional": true + }, "react-tabs": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-3.2.3.tgz", @@ -5111,6 +5312,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "devOptional": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -5121,6 +5323,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, "requires": { "picomatch": "^2.2.1" } @@ -5162,9 +5365,9 @@ "optional": true }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", "optional": true }, "regexp.prototype.flags": { @@ -5187,57 +5390,23 @@ "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "devOptional": true }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "devOptional": true }, "require-main-filename": { "version": "2.0.0", @@ -5313,7 +5482,8 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "devOptional": true }, "safe-regex-test": { "version": "1.0.0", @@ -5329,7 +5499,8 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true }, "sb-promise-queue": { "version": "2.1.0", @@ -5357,9 +5528,10 @@ } }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "requires": { "lru-cache": "^6.0.0" }, @@ -5368,6 +5540,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -5375,7 +5548,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -5391,7 +5565,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "shallowequal": { @@ -5594,7 +5768,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "ssh2": { @@ -5609,23 +5783,6 @@ "nan": "^2.17.0" } }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -5648,6 +5805,15 @@ "fs-extra": "^8.1.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "devOptional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-template": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", @@ -5688,25 +5854,6 @@ } } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, "string.prototype.trim": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", @@ -5740,27 +5887,11 @@ "es-abstract": "^1.20.4" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "requires": { "ansi-regex": "^5.0.1" } @@ -5787,17 +5918,18 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", - "optional": true + "optional": true, + "requires": {} }, "styled-components": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", - "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", "optional": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", + "@emotion/is-prop-valid": "^1.1.0", "@emotion/stylis": "^0.8.4", "@emotion/unitless": "^0.7.4", "babel-plugin-styled-components": ">= 1.12.0", @@ -5856,21 +5988,6 @@ "reftools": "^1.1.9", "yaml": "^1.10.0", "yargs": "^17.0.1" - }, - "dependencies": { - "oas-resolver": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", - "optional": true, - "requires": { - "node-fetch-h2": "^2.3.0", - "oas-kit-common": "^1.0.8", - "reftools": "^1.1.9", - "yaml": "^1.10.0", - "yargs": "^17.0.1" - } - } } }, "table": { @@ -5952,7 +6069,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "thriftrw": { @@ -5978,12 +6095,6 @@ } } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -5996,26 +6107,18 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "devOptional": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, "requires": { "is-number": "^7.0.0" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -6049,9 +6152,9 @@ } }, "tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==", "dev": true }, "tunnel": { @@ -6060,19 +6163,11 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true }, "type-check": { "version": "0.4.0", @@ -6113,9 +6208,9 @@ "dev": true }, "typed-rest-client": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz", - "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==", + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", "dev": true, "requires": { "qs": "^6.9.1", @@ -6166,7 +6261,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, + "devOptional": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -6189,7 +6284,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "devOptional": true }, "uuid": { "version": "3.4.0", @@ -6207,17 +6303,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -6228,9 +6313,9 @@ } }, "weapon-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/weapon-regex/-/weapon-regex-1.1.0.tgz", - "integrity": "sha512-DxCiBA0U7+5DSWs900rbkCScvLIyJgkYNrj1XRSLOq46mIHuIAMlwCilC1bVuAE+XBYq1+rjABSE/PfizKafxQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/weapon-regex/-/weapon-regex-1.1.1.tgz", + "integrity": "sha512-b0RmqduiSUKyKFamrpU+UK78Jm65/6CgKq1zoWFaS9PM7vwNK4RWrjmX1jREs3pLmG7botsgMLVOltxDR7RGRw==", "dev": true }, "webidl-conversions": { @@ -6312,9 +6397,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { @@ -6363,40 +6448,11 @@ } } }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "devOptional": true }, "write-file-atomic": { "version": "3.0.3", @@ -6414,7 +6470,8 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "optional": true + "optional": true, + "requires": {} }, "xorshift": { "version": "1.2.0", @@ -6431,13 +6488,14 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true }, "yaml": { "version": "1.10.2", @@ -6488,7 +6546,8 @@ "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "devOptional": true }, "yargs-unparser": { "version": "2.0.0", diff --git a/package.json b/package.json index 342cbafe..c5b498ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "f5-declarative-onboarding", - "version": "1.39.0-4", + "version": "1.40.0-8", "description": "F5 Declarative Onboarding", "main": "index.js", "repository": { @@ -19,7 +19,7 @@ "author": "F5 Networks", "license": "Apache-2.0", "dependencies": { - "@f5devcentral/atg-shared-utilities": "^0.7.0", + "@f5devcentral/atg-shared-utilities": "^0.10.1", "@f5devcentral/f5-cloud-libs": "^4.29.0", "@f5devcentral/f5-teem": "^1.6.1", "ajv": "6.12.6", @@ -28,10 +28,10 @@ "uuid": "3.4.0" }, "devDependencies": { - "@f5devcentral/atg-shared-utilities-dev": "^0.2.13", + "@f5devcentral/atg-shared-utilities-dev": "^0.2.14", "@f5devcentral/eslint-config-f5-atg": "^0.1.8", - "@stryker-mutator/core": "^7.0.2", - "@stryker-mutator/mocha-runner": "^7.0.2", + "@stryker-mutator/core": "^7.1.1", + "@stryker-mutator/mocha-runner": "^7.1.1", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "colors": "^1.4.0", @@ -42,7 +42,6 @@ "mocha-multi-reporters": "^1.5.1", "nock": "10.0.0", "nyc": "^15.1.0", - "request": "^2.88.2", "sinon": "7.5.0", "winston": "^2.4.7" }, @@ -67,7 +66,7 @@ "extends": "@f5devcentral/eslint-config-f5-atg" }, "optionalDependencies": { - "@redocly/cli": "^1.0.0-beta.128", + "@redocly/cli": "^1.0.2", "node-ssh": "^13.1.0" } } diff --git a/scripts/build/schema-to-rst.js b/scripts/build/schema-to-rst.js index e7477e8a..ac2868f1 100644 --- a/scripts/build/schema-to-rst.js +++ b/scripts/build/schema-to-rst.js @@ -88,7 +88,8 @@ function getDefault(property) { } else if (typeof property.default === 'object') { pDefault = JSON.stringify(property.default); } else if (typeof property.default === 'string') { - pDefault = `"${property.default}"`; + // This replaces newline characters in a way that does NOT break our documentation + pDefault = `"${property.default.replace(/\n/gm, '\\\\n')}"`; } else { pDefault = property.default; } diff --git a/src/lib/configItems.json b/src/lib/configItems.json index f41a670d..a3e09860 100644 --- a/src/lib/configItems.json +++ b/src/lib/configItems.json @@ -8,7 +8,9 @@ { "id": "guiAudit", "newId": "guiAuditLog", "truth": "enabled", "falsehood": "disabled", "skipWhenOmitted": true }, { "id": "mgmtDhcp", "newId": "mgmtDhcpEnabled", "truth": "enabled", "falsehood": "disabled", "skipWhenOmitted": true }, { "id": "guiSecurityBanner", "truth": "enabled", "falsehood": "disabled", "skipWhenOmitted": "true" }, - { "id": "guiSecurityBannerText" } + { "id": "guiSecurityBannerText" }, + { "id": "usernamePrompt" }, + { "id": "passwordPrompt" } ], "nameless": true }, @@ -214,7 +216,8 @@ "schemaClass": "RoutingPrefixList", "properties": [ { "id": "name" }, - { "id": "entriesReference", "dereferenceId": "entries" } + { "id": "entriesReference", "dereferenceId": "entries" }, + { "id": "routeDomain" } ], "references": { "entriesReference": [ @@ -1270,6 +1273,36 @@ ] } }, + { + "path": "/tm/asm/virus-detection-server", + "schemaClass": "SecurityWaf", + "schemaMerge": { + "action": "add", + "path": ["antiVirusProtection"] + }, + "requiredModules": [{ "module": "asm" }], + "properties": [ + { "id": "guaranteeEnforcement", "newId": "guaranteeEnforcementEnabled" }, + { "id": "hostname" }, + { "id": "port" } + ], + "nameless": true + }, + { + "path": "/tm/asm/advanced-settings", + "schemaClass": "SecurityWaf", + "requiredModules": [{ "module": "asm" }], + "properties": [ + { "id": "id" }, + { "id": "name" }, + { "id": "value" } + ], + "declaration": { + "customFunctions": [ + { "id": "convertAdvancedSettings" } + ] + } + }, { "schemaClass": "License", "nameless": true, diff --git a/src/lib/configManager.js b/src/lib/configManager.js index 12b3774f..95bd9597 100644 --- a/src/lib/configManager.js +++ b/src/lib/configManager.js @@ -353,6 +353,16 @@ class ConfigManager { patchGSLBProberPool.call(this, patchedItem); } + if (schemaClass === 'SecurityWaf') { + currentConfig[schemaClass] = patchSecurityWaf.call( + this, + schemaMerge, + currentConfig[schemaClass], + patchedItem + ); + patchedItem = null; + } + if (patchedItem) { if (!currentConfig[schemaClass]) { currentConfig[schemaClass] = {}; @@ -441,6 +451,15 @@ class ConfigManager { ); } + if (schemaClass === 'SecurityWaf') { + patchedItem = patchSecurityWaf.call( + this, + schemaMerge, + currentConfig[schemaClass], + patchedItem + ); + } + currentConfig[schemaClass] = patchedItem; getReferencedPaths.call( this, @@ -1329,6 +1348,21 @@ function patchVxlanTunnels(item, vxlan, translateToNewId) { mapSchemaMerge.call(this, item, vxlan, { action: 'add' }); } +function patchSecurityWaf(schemaMerge, wafClass, wafItem) { + if (!schemaMerge) { + if (!wafClass.advancedSettings) { + wafClass.advancedSettings = {}; + } + wafClass.advancedSettings[wafItem.name] = JSON.parse(JSON.stringify(wafItem)); + delete wafClass.advancedSettings[wafItem.name].name; + return wafClass; + } + + const wafClassCopy = !wafClass ? {} : JSON.parse(JSON.stringify(wafClass)); + const patchedItem = Object.assign({}, wafItem); + return mapSchemaMerge.call(this, wafClassCopy, patchedItem, schemaMerge); +} + /** * GTM objects have both enabled and disabled properties * instead of one prop with boolean value diff --git a/src/lib/declarationHandler.js b/src/lib/declarationHandler.js index f57c888c..2e2e3cb3 100644 --- a/src/lib/declarationHandler.js +++ b/src/lib/declarationHandler.js @@ -38,6 +38,7 @@ const TraceManager = require('./traceManager'); const RoutingAccessListValidator = require('./routingAccessListValidator'); const configItems = require('./configItems.json'); const doUtil = require('./doUtil'); +const ADVANCED_SETTINGS_IDS = require('./sharedConstants').WAF_ADVANCED_SETTINGS; const ralv = new RoutingAccessListValidator(); @@ -142,6 +143,7 @@ class DeclarationHandler { applyTunnelFixes.call(this, parsedNewDeclaration); applyManagementRouteFixes.call(this, parsedNewDeclaration); origLdapCertData = applyLdapCertFixes.call(this, parsedNewDeclaration); + applySecurityWafFixes.call(this, parsedNewDeclaration); }) .then(() => removeEmptyObjects(parsedNewDeclaration)) .then(() => removeEmptyObjects(parsedOldDeclaration)) @@ -1206,6 +1208,30 @@ function applyManagementRouteFixes(declaration) { }); } +/** + * Convert the advancedSettings array to an object. + * + * @param {Object} declaration - user provided declaration + */ +function applySecurityWafFixes(declaration) { + const securityWaf = declaration.Common.SecurityWaf; + + if (securityWaf && Array.isArray(securityWaf.advancedSettings)) { + const advancedSettings = {}; + const originalAdvancedSettings = this.state.originalConfig.Common.SecurityWaf + ? this.state.originalConfig.Common.SecurityWaf.advancedSettings : {}; + + securityWaf.advancedSettings.forEach((setting) => { + advancedSettings[setting.name] = { + value: setting.value, + id: ADVANCED_SETTINGS_IDS[setting.name] + }; + }); + + securityWaf.advancedSettings = Object.assign(originalAdvancedSettings, advancedSettings); + } +} + function processHandler(Handler, declaration, bigIp, eventEmitter, state) { return new Handler(declaration, bigIp, eventEmitter, state).process(); } diff --git a/src/lib/deleteHandler.js b/src/lib/deleteHandler.js index 56949afb..325ddc2d 100644 --- a/src/lib/deleteHandler.js +++ b/src/lib/deleteHandler.js @@ -37,13 +37,13 @@ const DELETABLE_CLASSES = [ 'VLAN', 'Trunk', 'RouteMap', + 'RoutingPrefixList', 'RouteDomain', 'RemoteAuthRole', 'ManagementRoute', 'Tunnel', 'RoutingAccessList', 'RoutingAsPath', - 'RoutingPrefixList', 'GSLBMonitor', 'SnmpTrapDestination', 'SnmpCommunity', diff --git a/src/lib/inspectHandler.js b/src/lib/inspectHandler.js index a0515ade..9f8714da 100644 --- a/src/lib/inspectHandler.js +++ b/src/lib/inspectHandler.js @@ -438,6 +438,15 @@ const customFunctions = { configObject.collectStaleRulesEnabled = configObject.collectStaleRulesEnabled.collect; return [configKey, configObject]; }, + // SecurityWaf + convertAdvancedSettings: (configKey, configObject) => { + if (configObject.advancedSettings) { + configObject.advancedSettings = Object.keys(configObject.advancedSettings).map((setting) => ( + { name: setting, value: configObject.advancedSettings[setting].value } + )); + } + return [configKey, configObject]; + }, // Some items with schemaMerge are skipped in the general handling but // should be processed by processItem anyway remapItemWithSchemaMerge: (configKey, configObject) => [configKey, configObject] diff --git a/src/lib/networkHandler.js b/src/lib/networkHandler.js index 319859f6..c5e9d8f3 100644 --- a/src/lib/networkHandler.js +++ b/src/lib/networkHandler.js @@ -148,7 +148,12 @@ class NetworkHandler { }) .then((result) => { updateStatus(status, result); - this.logger.info('Checking RoutingBGP and RouteMap'); + this.logger.info('Checking RouteMap'); + return handleRouteMap.call(this); + }) + .then((result) => { + updateStatus(status, result); + this.logger.info('Checking RoutingBGP'); return handleRoutingBGP.call(this); }) .then((result) => { @@ -743,7 +748,7 @@ function handleRouteDomain() { } return this.bigIp.createOrModify(PATHS.RouteDomain, rd0Body); }) - .then(() => this.bigIp.transaction(commands)) + .then(() => (commands.length === 0 ? Promise.resolve() : this.bigIp.transaction(commands))) .catch((err) => { this.logger.severe(`Error creating RouteDomains: ${err.message}`); throw err; @@ -957,8 +962,13 @@ function handleRoutingAccessList() { } function handleRoutingPrefixList() { + if (!this.declaration.Common.RoutingPrefixList) { + return Promise.resolve(); + } + const promises = []; - doUtil.forEach(this.declaration, 'RoutingPrefixList', (tenant, list) => { + doUtil.forEach(this.declaration, 'RoutingPrefixList', (partition, list) => { + const transaction = []; if (list && Object.keys(list).length !== 0) { const entries = {}; @@ -974,13 +984,43 @@ function handleRoutingPrefixList() { const body = { name: list.name, - partition: tenant, + partition, + routeDomain: list.routeDomain, entries }; - promises.push( - this.bigIp.createOrModify(PATHS.RoutingPrefixList, body, null, cloudUtil.MEDIUM_RETRY) - ); + const bodyNoEntries = JSON.parse(JSON.stringify(body)); + delete bodyNoEntries.entries; + + const bodyNoRouteDomain = JSON.parse(JSON.stringify(body)); + delete bodyNoRouteDomain.routeDomain; + + // routeDomain is read-only and in some cases if another object refers to the RoutingPrefixList they + // both must have the same routeDomain. Modifying routeDomain in a delete-create transaction somehow gets + // around this but for some reason the entries property is buggy in this transaction. Leaving entries out of + // the delete-create transaction followed up by a modify that leaves out the routeDomain seems to work. + const currentRouteDomain = doUtil.getDeepValue(this.state.currentConfig.Common, `RoutingPrefixList.${body.name}.routeDomain`); + if (currentRouteDomain && currentRouteDomain !== body.routeDomain) { + transaction.push({ + method: 'delete', + path: `${PATHS.RoutingPrefixList}/~${partition}~${list.name}` + }); + transaction.push({ + method: 'create', + path: PATHS.RoutingPrefixList, + body: bodyNoEntries + }); + promises.push(promiseUtil.series([ + () => this.bigIp.transaction(transaction), + () => this.bigIp.createOrModify( + PATHS.RoutingPrefixList, bodyNoRouteDomain, null, cloudUtil.MEDIUM_RETRY + ) + ])); + } else { + promises.push( + this.bigIp.createOrModify(PATHS.RoutingPrefixList, body, null, cloudUtil.MEDIUM_RETRY) + ); + } } }); @@ -996,21 +1036,9 @@ function handleRouteMap() { return Promise.resolve(); } - const routeMapsToDelete = []; - const routeMapsToCreateOrModify = []; - - doUtil.forEach(this.declaration, 'RouteMap', (tenant, map) => { - // If RouteMap already exists with a different route domain then - // must delete it first and recreate later because routeDomain cannot be changed. - if (this.state.currentConfig.Common.RouteMap - && this.state.currentConfig.Common.RouteMap[map.name] - && this.state.currentConfig.Common.RouteMap[map.name].routeDomain !== map.routeDomain) { - routeMapsToDelete.push({ - tenant, - name: map.name - }); - } - + const promises = []; + doUtil.forEach(this.declaration, 'RouteMap', (partition, map) => { + const transaction = []; if (map && Object.keys(map).length !== 0) { const entries = {}; if (map.entries) { @@ -1022,46 +1050,55 @@ function handleRouteMap() { }); } - const routeMapBody = { + const body = { name: map.name, - partition: tenant, + partition, entries, routeDomain: map.routeDomain }; - routeMapsToCreateOrModify.push(routeMapBody); - } - }); + const bodyNoEntries = JSON.parse(JSON.stringify(body)); + delete bodyNoEntries.entries; - return Promise.resolve() - .then(() => { - const promises = []; - routeMapsToDelete.forEach((map) => { - promises.push( - this.bigIp.delete(`${PATHS.RouteMap}/~${map.tenant}~${map.name}`, null, null, cloudUtil.NO_RETRY) - ); - }); - return Promise.all(promises); - }) - .then(() => { - const promises = []; - routeMapsToCreateOrModify.forEach((map) => { + const bodyNoRouteDomain = JSON.parse(JSON.stringify(body)); + delete bodyNoRouteDomain.routeDomain; + + // routeDomain is read-only. Modifying routeDomain in a delete-create transaction somehow gets around this + // but for some reason the entries property is buggy in this transaction. Leaving entries out of the + // delete-create transaction followed up by a modify that leaves out the routeDomain seems to work. + const currentRouteDomain = doUtil.getDeepValue(this.state.currentConfig.Common, `RouteMap.${body.name}.routeDomain`); + if (currentRouteDomain && currentRouteDomain !== body.routeDomain) { + transaction.push({ + method: 'delete', + path: `${PATHS.RouteMap}/~${partition}~${map.name}` + }); + transaction.push({ + method: 'create', + path: PATHS.RouteMap, + body: bodyNoEntries + }); + promises.push(promiseUtil.series([ + () => this.bigIp.transaction(transaction), + () => this.bigIp.createOrModify(PATHS.RouteMap, bodyNoRouteDomain, null, cloudUtil.MEDIUM_RETRY) + ])); + } else { promises.push( - this.bigIp.createOrModify(PATHS.RouteMap, map, null, cloudUtil.NO_RETRY) + this.bigIp.createOrModify(PATHS.RouteMap, body, null, cloudUtil.NO_RETRY) ); - }); - return Promise.all(promises); - }) + } + } + }); + + return Promise.all(promises) .catch((err) => { - this.logger.severe(`Error creating route maps: ${err.message}`); + this.logger.severe(`Error creating RouteMap: ${err.message}`); throw err; }); } function handleRoutingBGP() { if (!this.declaration.Common.RoutingBGP) { - this.logger.info('Checking RouteMap'); - return handleRouteMap.call(this); + return Promise.resolve(); } let promises = []; @@ -1098,12 +1135,6 @@ function handleRoutingBGP() { throw err; }); }) - .then(() => { - // This is the best time to do this if a RouteMap referenced by a peer group in the singleton RoutingBGP has - // a route domain change. - this.logger.info('Checking RouteMap before creating RoutingBGP'); - return handleRouteMap.call(this); - }) .then(() => { promises = []; doUtil.forEach(this.declaration, 'RoutingBGP', (tenant, bgp) => { diff --git a/src/lib/securityHandler.js b/src/lib/securityHandler.js index 4583d230..0fd55122 100644 --- a/src/lib/securityHandler.js +++ b/src/lib/securityHandler.js @@ -18,6 +18,8 @@ const Logger = require('./logger'); const PATHS = require('./sharedConstants').PATHS; +const ADVANCED_SETTINGS_IDS = require('./sharedConstants').WAF_ADVANCED_SETTINGS; +const doUtil = require('./doUtil'); /** * Handles security parts of a declaration. @@ -55,6 +57,10 @@ class SecurityHandler { this.logger.fine('Checking SecurityAnalytics'); return handleSecurityAnalytics.call(this); }) + .then(() => { + this.logger.fine('Checking SecurityWaf'); + return handleSecurityWaf.call(this); + }) .catch((err) => { this.logger.severe(`Error processing security declaration: ${err.message}`); return Promise.reject(err); @@ -72,4 +78,27 @@ function handleSecurityAnalytics() { return Promise.resolve(); } +function handleSecurityWaf() { + if (this.declaration.Common.SecurityWaf) { + const promises = []; + const virusProtection = this.declaration.Common.SecurityWaf.antiVirusProtection; + const advancedSettings = this.declaration.Common.SecurityWaf.advancedSettings; + + if (virusProtection) { + promises.push(this.bigIp.modify(PATHS.AntiVirusProtection, virusProtection)); + } + + if (advancedSettings) { + Object.keys(advancedSettings).forEach((setting) => { + const id = ADVANCED_SETTINGS_IDS[setting]; + promises.push(this.bigIp.modify(`${PATHS.WafAdvancedSettings}/${id}`, advancedSettings[setting])); + }); + } + + return Promise.all(promises) + .then(() => doUtil.restartService(this.bigIp, 'asm', { taskId: this.state.id })); + } + return Promise.resolve(); +} + module.exports = SecurityHandler; diff --git a/src/lib/sharedConstants.js b/src/lib/sharedConstants.js index b90114fa..bd389c94 100644 --- a/src/lib/sharedConstants.js +++ b/src/lib/sharedConstants.js @@ -23,7 +23,7 @@ */ module.exports = { BASE_URL: 'https://localhost/mgmt/shared/declarative-onboarding', - MASK_REGEX: /pass(word|phrase)|secret|privateKey/i, + MASK_REGEX: /pass(word|phrase)\b|secret|privateKey/i, ENDPOINT_MAX_TIMEOUT: 60000, ENDPOINTS: { CONFIG: 'config', @@ -33,6 +33,7 @@ module.exports = { }, PATHS: { Analytics: '/tm/analytics/global-settings', + AntiVirusProtection: '/tm/asm/virus-detection-server', AuthLdap: '/tm/auth/ldap', AuthPartition: '/tm/auth/partition', AuthRadius: '/tm/auth/radius', @@ -92,7 +93,8 @@ module.exports = { Uploads: '/shared/file-transfer/uploads', User: '/tm/auth/user', VLAN: '/tm/net/vlan', - VXLAN: '/tm/net/tunnels/vxlan' + VXLAN: '/tm/net/tunnels/vxlan', + WafAdvancedSettings: '/tm/asm/advanced-settings' }, STATUS: { STATUS_OK: 'OK', @@ -122,5 +124,52 @@ module.exports = { CA_CERT: 'do_ldapCaCert.crt', CLIENT_CERT: 'do_ldapClientCert.crt', CLIENT_KEY: 'do_ldapClientCert.key' + }, + WAF_ADVANCED_SETTINGS: { + allow_all_cookies_at_entry_point: 'OSEAbgBE9OsgvUSxORliXw', + bypass_upon_asm_down: 'hKQW-1omECNHugcHQIcgAQ', + bypass_upon_load: 'S7hzR_qTwol9Kkz9Lhjygg', + cookie_expiration_time_out: 'Bo68NqP9roUE8Vv2NO-29Q', + cookie_httponly_attr: 'yWZ5eGK1ntnYaTxblMNyww', + cookie_max_age: '1XJcDTbBxqP0GtOcdQzF0g', + cookie_renewal_time_stamp: 'Y2xm8sicyUqvtYW7XdazLQ', + ecard_max_http_req_uri_len: '3Rteo2zkBA9z8nzwsCgrvQ', + ecard_regexp_email: 'Xd48JLria9Xn13bh9hs5bA', + ecard_regexp_decimal: 'pKEKBwZiy7KE4hcSP218sQ', + ecard_regexp_phone: 'B6n-QlJdEAmu35GYHCjcaQ', + icap_uri: 'G0OtDDhrirtc3DAvVIL3qA', + LogSignatures: 'DL-dTgOI8EkErPNb89CqHQ', + long_request_buffer_size: 'UGv8BV7NbLZZP4hgvBkk7g', + long_request_mem_percentage: 'EmVXcGrEQcyx4D85aPY0tw', + max_filtered_html_length: 'egIwkT5XGat_3phe_TYVxw', + max_json_policy_size: '4NRiSGFR-qvXsN8VM7oKiw', + max_login_request_body_buffer_size: 'KHYdzmoL_l6luO6k9Sy3Vg', + max_raw_request_len: 'AG4WUXljvu9lM6AH8dAKXg', + max_slow_transactions: 'E6ZRTf9B4t2VBqr7VyTx5w', + MaxFtpSessions: 'y-ZbMLuoa2aN7qp2lBYq4Q', + MaximumCryptographicOperations: 'xwVHrYB2wHTWW16ap_I4uA', + MaxSmtpSessions: '-UfFoGnprUbAdfuYE3l44w', + MaxViolationEntries: 'pF09Tjd_uNrk215bSVrdbg', + policy_history_max_total_size: 'vO3CxwQgcbycM7iTqbnl9w', + policy_history_min_retained_versions: 'eF-vzrQl2fwoXWA1U1o0IQ', + ProtocolIndication: 'qUrdG89jw8HflvMKJfOkQA', + PRXRateLimit: '4ZznWiwDgH79_TZoIjkRxw', + request_buffer_size: 'QOvKhWpQAb2i4vlockHsYw', + reporting_search_timeout: 'bBCPejaHht0_tgcJYQl7Qg', + ResponseBufferSize: 'mxmQIHLzWRzL5DzQaae3Lw', + restart_upon_config_update_error: 'h4cPIefSai5czHbH8649MA', + RWLightThreads: '5kx5oMhJWU1JXr6jagAlkg', + RWThreads: '9ZPR5pHmVfc5t-FfruOC-w', + sa_login_expiration_timeout: 'NLl9aGiOQKNfx1ZWWQvdOg', + send_content_events: 'JCJCtCv20xiFU8Xf7D5Epg', + single_page_application: 'GqhjvcKleDusK8-xl1lC4w', + slow_transaction_timeout: '1j5NC6SxNqHgHd4KCkFERQ', + total_umu_max_size: '_nYculxq-fBhRqH2GVBfXw', + total_xml_memory: 'O6z_jDkjBalpmAiwURU9HQ', + virus_header_name: 'BBDs36E0u0ZR0GtxrD0yEA', + WhiteHatIP1: 'Wa3cDp35bC9aXWWoXLr9bg', + WhiteHatIP2: 'JGsWl_Fa6RT2KFZUFEHENA', + WhiteHatIP3: 'oHZc1VsaSuoWTQGFtnr6Sg', + WhiteHatIP4: 'e17lg9g7L_1aXWM_RJvwUg' } }; diff --git a/src/lib/systemHandler.js b/src/lib/systemHandler.js index 44fb5f9a..83085e8f 100644 --- a/src/lib/systemHandler.js +++ b/src/lib/systemHandler.js @@ -490,6 +490,17 @@ function handleSystem() { if (Object.keys(guiSecuritySettings).length !== 0) { promises.push(this.bigIp.modify(PATHS.SysGlobalSettings, guiSecuritySettings)); } + + const promptSettings = {}; + if (system.usernamePrompt) { + promptSettings.usernamePrompt = system.usernamePrompt; + } + if (system.passwordPrompt) { + promptSettings.passwordPrompt = system.passwordPrompt; + } + if (Object.keys(promptSettings).length !== 0) { + promises.push(this.bigIp.modify(PATHS.SysGlobalSettings, promptSettings)); + } } return Promise.all(promises); diff --git a/src/schema/1.40.0/analytics.schema.json b/src/schema/1.40.0/analytics.schema.json new file mode 100644 index 00000000..61100225 --- /dev/null +++ b/src/schema/1.40.0/analytics.schema.json @@ -0,0 +1,139 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/analytics.schema.json", + "title": "F5 BIG-IP Declarative Onboarding Global Analytics declaration", + "description": "Global analytics properties for onboarding a BIG-IP.", + "if": { + "required": ["class"], + "properties": { "class": { "const": "Analytics" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains global analytics configuration", + "type": "string", + "const": "Analytics" + }, + "debugEnabled": { + "description": "Enable debug mode. If debug mode is disabled, internal statistics are collected only if interval is set to the default value (300 seconds)", + "type": "boolean", + "default": false + }, + "interval": { + "description": "Analytics data collection interval in seconds. If this interval is different from the default value (300 seconds), internal statistics are not collected unless debugEnabled is set to true. Minimum interval is 20 seconds, maximum interval is 300 seconds.", + "type": "integer", + "minimum": 20, + "maximum": 300, + "default": 300 + }, + "sourceId": { + "description": "Unique value to signify the source of data", + "type": "string" + }, + "tenantId": { + "description": "Unique id for the tenant using the analytics backend system", + "type": "string" + }, + "offboxProtocol": { + "description": "Protocol for communication with offbox analytics application", + "type": "string", + "enum": ["https", "tcp"] + }, + "offboxTcpAddresses": { + "description": "Server IP addresses used only if the 'tcp/https' protocol is chosen", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6"}, + { "format": "json-pointer" } + ] + } + }, + "offboxTcpPort": { + "description": "Server TCP port for the server IP addresses used only if the 'tcp' protocol is chosen", + "type": "number", + "minimum": 0, + "maximum": 65535 + }, + "offboxEnabled": { + "description": "Enables all communication with the offbox application on the global level", + "type": "boolean", + "default": false + } + }, + "allOf": [ + { + "if": { + "properties": { + "offboxEnabled" : { "const": true } + }, + "required": ["offboxEnabled"] + }, + "then": { + "required": ["offboxProtocol"] + } + }, + { + "if": { + "properties": { + "offboxTcpPort": { + "minimum": 1 + } + }, + "required": ["offboxTcpPort"] + }, + "then": { + "required": ["offboxTcpAddresses", "offboxProtocol"] + } + }, + { + "if": { + "properties": { + "offboxTcpAddresses": { + "minItems": 1 + } + }, + "required": ["offboxTcpAddresses"] + }, + "then": { + "required": ["offboxTcpPort", "offboxProtocol"] + } + }, + { + "if": { + "properties": { + "offboxProtocol": { "enum": ["tcp", "https"] } + }, + "required": ["offboxProtocol"] + }, + "then": { + "properties": { + "offboxTcpPort": { + "minimum": 1 + }, + "offboxTcpAddresses": { + "minItems": 1 + } + }, + "required": ["offboxTcpAddresses", "offboxTcpPort"] + } + }, + { + "if": { + "properties": { + "offboxProtocol": { "enum": ["https"] } + }, + "required": ["offboxProtocol"] + }, + "then": { + "required": ["sourceId"] + } + } + ], + "additionalProperties": false + } +} diff --git a/src/schema/1.40.0/auth.schema.json b/src/schema/1.40.0/auth.schema.json new file mode 100644 index 00000000..aee0a016 --- /dev/null +++ b/src/schema/1.40.0/auth.schema.json @@ -0,0 +1,704 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/auth.schema.json", + "title": "F5 BIG-IP Declarative Onboarding Authentication declaration", + "description": "Authentication properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "RemoteAuthRole" } } + }, + "then": { + "oneOf": [ + { "$ref": "#/definitions/remoteAuthRole" } + ] + } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "Authentication" } } + }, + "then": { + "oneOf": [ + { "$ref": "#/definitions/remoteInfo" } + ] + } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "PasswordPolicy" } } + }, + "then": { + "$ref": "#/definitions/passwordPolicy" + } + } + ], + "definitions": { + "passwordPolicy": { + "required": ["class"], + "type": "object", + "description": "Password policy info.", + "properties": { + "class": { + "description": "Indicates that this property contains password policy configuration.", + "type": "string", + "const": "PasswordPolicy" + }, + "expirationWarningDays": { + "description": "Specifies the number of days prior to password expiration that the system sends a warning message to users.", + "type": "integer", + "minimum": 1, + "maximum": 255, + "default": 7 + }, + "minLength": { + "description": "Specifies the minimum number of characters in a valid password.", + "type": "integer", + "minimum": 6, + "maximum": 255, + "default": 6 + }, + "minDurationDays": { + "description": "Specifies the minimum number of days a password is valid.", + "type": "integer", + "minimum": 0, + "maximum": 255, + "default": 0 + }, + "maxDurationDays": { + "description": "Specifies the maximum number of days a password is valid.", + "type": "integer", + "minimum": 0, + "maximum": 99999, + "default": 99999 + }, + "lockoutDurationSeconds": { + "description": "Specifies number of seconds in which to automatically reinstate users after being locked out. 0 means users must be manually reinstated. This is for BIG-IP 15.1+", + "type": "integer", + "minimum": 0, + "maximum": 999999, + "default": 0 + }, + "maxLoginFailures": { + "description": "Specifies the number of consecutive unsuccessful login attempts that the system allows before locking out the user. 0 means disabled.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "passwordMemory": { + "description": "Specifies the number of former passwords that the BIG-IP system retains to prevent the user from reusing a recent password.", + "type": "integer", + "minimum": 0, + "maximum": 127, + "default": 0 + }, + "policyEnforcementEnabled": { + "description": "Enables or disables the password policy.", + "type": "boolean", + "default": true + }, + "requiredUppercase": { + "description": "Specifies the number of uppercase alpha characters that must be present in a password for the password to be valid.", + "type": "integer", + "minimum": 0, + "maximum": 127, + "default": 0 + }, + "requiredLowercase": { + "description": "Specifies the number of lowercase alpha characters that must be present in a password for the password to be valid.", + "type": "integer", + "minimum": 0, + "maximum": 127, + "default": 0 + }, + "requiredNumeric": { + "description": "Specifies the number of numeric characters that must be present in a password for the password to be valid.", + "type": "integer", + "minimum": 0, + "maximum": 127, + "default": 0 + }, + "requiredSpecial": { + "description": "Specifies the number of special characters that must be present in a password for the password to be valid.", + "type": "integer", + "minimum": 0, + "maximum": 127, + "default": 0 + } + }, + "additionalProperties": false + }, + "remoteInfo": { + "required": ["class", "enabledSourceType"], + "type": "object", + "description": "Remote authentication info.", + "properties": { + "class": { + "description": "Indicates that this property contains authentication configuration.", + "type": "string", + "const": "Authentication" + }, + "enabledSourceType": { + "description": "Type of remote authentication source to enable for the system.", + "type": "string", + "enum": ["radius", "local", "tacacs", "ldap", "activeDirectory"], + "default": "local" + }, + "remoteUsersDefaults": { + "description": "The default values that the BIG-IP system applies to any user account that is not part of a remotely-stored user group.", + "type": "object", + "required": [ "partitionAccess", "terminalAccess", "role" ], + "properties": { + "role": { + "description": "Role for the remote users.", + "type": "string", + "enum": [ + "acceleration-policy-editor", + "admin", + "application-editor", + "auditor", + "certificate-manager", + "firewall-manager", + "fraud-protection-manager", + "guest", + "irule-manager", + "manager", + "no-access", + "operator", + "resource-admin", + "user-manager", + "web-application-security-administrator", + "web-application-security-editor" + ], + "default": "no-access" + }, + "partitionAccess": { + "description": "Default accessible partitions for remote users.", + "type": "string", + "enum": ["Common", "all"], + "default": "all" + }, + "terminalAccess": { + "description": "Default terminal access for remote users.", + "type": "string", + "enum": ["tmsh", "disabled"], + "default": "disabled" + } + }, + "additionalProperties": false + }, + "fallback": { + "description": "Specifies that the system uses the Local authentication method if the remote authentication method is not available.", + "type": "boolean", + "default": false + }, + "radius": { + "$ref": "#/definitions/radius" + }, + "tacacs": { + "$ref": "#/definitions/tacacs" + }, + "ldap": { + "$ref": "#/definitions/ldap" + } + }, + "allOf": [ + { + "if": { + "required": ["enabledSourceType"], + "properties": { "enabledSourceType": { "const": "radius"} } + }, + "then": { "required": ["radius"] } + }, + { + "if": { + "required": ["enabledSourceType"], + "properties": { "enabledSourceType": { "const": "tacacs"} } + }, + "then": { "required": ["tacacs"] } + }, + { + "if": { + "required": ["enabledSourceType"], + "properties": { "enabledSourceType": { "oneOf": [ + { "const": "ldap" }, + { "const": "activeDirectory" } + ] } } + }, + "then": { "required": ["ldap"] } + } + ], + "additionalProperties": false + }, + "variableString": { + "description": "Variable string value. Should always start with %.", + "type": "string", + "pattern": "^%.+" + }, + "remoteAuthRole": { + "description": "Creates a file used by LDAP, Active Directory(r), RADIUS, or TACACS+ server to determine specific access rights.", + "type": "object", + "required": [ "class", "attribute", "lineOrder", "userPartition" ], + "properties": { + "class": { + "description": "Indicates that this property contains RemoteAuthRole configuration.", + "type": "string", + "const": "RemoteAuthRole" + }, + "attribute": { + "description": "Specifies an attribute-value pair that an authentication server supplies to the BIG-IP system to match against entries in /config/bigip/auth/remoterole. The specified pair typically identifies users with access rights in common. This option is required.", + "type": "string" + }, + "console": { + "description": "Specifes if the remotely-authenticated users have tmsh console access or not. Accepted values are 'disabled' and 'tmsh'.", + "oneOf": [ + { + "type": "string", + "enum": [ + "disabled", + "tmsh" + ] + }, + { + "$ref": "#/definitions/variableString" + } + ], + "default": "disabled" + }, + "remoteAccess": { + "description": "Enables the specified group of remotely-authenticated users, remote access.", + "type": "boolean", + "default": false + }, + "lineOrder": { + "description": "The BIG-IP only allows one role per user for each partition/tenant. Because some remote servers allow multiple user roles, the BIG-IP uses the lineOrder parameter to choose one of the conflicting roles for the user at login time. In these cases, the system chooses the role with the lowest line-order number. See line order in the BIG-IP documentation for more information and examples.", + "type": "integer", + "minimum": 0, + "maximum": 4294967295 + }, + "role": { + "description": "Specifies the role that you want to grant to the specified group of remotely-authenticated users.", + "oneOf": [ + { + "type": "string", + "enum": [ + "admin", + "application-editor", + "auditor", + "certificate-manager", + "firewall-manager", + "fraud-protection-manager", + "guest", + "irule-manager", + "manager", + "no-access", + "operator", + "resource-admin", + "user-manager", + "web-application-security-administrator", + "web-application-security-editor" + ] + }, + { + "$ref": "#/definitions/variableString" + } + ], + "default": "no-access" + }, + "userPartition": { + "description": "Specifies the BIG-IP partition to which you are assigning access to the specified group of remotely-authenticated users. The default value is Common. This option is required.", + "oneOf": [ + { + "type": "string", + "enum": [ + "all", + "Common" + ] + }, + { + "$ref": "#/definitions/variableString" + } + ], + "default": "Common" + } + }, + "additionalProperties": false + }, + "radius": { + "description": "Remote RADIUS authentication info.", + "type": "object", + "required": [ "servers"], + "properties": { + "serviceType": { + "description": "Type of service used for the RADIUS server.", + "type": "string", + "enum": [ + "administrative", + "authenticate-only", + "call-check", + "callback-administrative", + "callback-framed", + "callback-login", + "callback-nas-prompt", + "default", + "framed", + "login", + "nas-prompt", + "outbound" + ], + "default": "default" + }, + "servers": { + "description": "RADIUS servers settings", + "required": ["primary"], + "properties": { + "primary": { + "description": "Server connection settings for the primary RADIUS server", + "allOf": [ {"$ref": "#/definitions/radiusServer"} ] + }, + "secondary": { + "description": "Server connection settings for the secondary RADIUS server (optional)", + "allOf": [ {"$ref": "#/definitions/radiusServer"} ] + } + }, + "additionalProperties": false + } + } + }, + "radiusServer": { + "description": "RADIUS server connection settings.", + "type": "object", + "required": [ "server", "secret" ], + "properties": { + "server": { + "type": "string", + "description": "The RADIUS server IP address or hostname.", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ] + }, + "port": { + "type": "integer", + "description": "Port to use when connecting to the RADIUS server.", + "default": 1812 + }, + "secret": { + "description": "Password to use when connection to the RADIUS server.", + "type": "string" + } + } + }, + "tacacs": { + "description": "TACACS+ authentication info", + "type": "object", + "required": [ "secret", "servers", "service" ], + "properties": { + "accounting": { + "description": "Specifies how the system returns accounting information, such as which services users access and how much network resources they consume, to the TACACS+ server. The default setting is Send to first available server.", + "type": "string", + "enum": [ + "send-to-all-servers", + "send-to-first-server" + ], + "default": "send-to-first-server" + }, + "authentication": { + "description": "Specifies the process the system employs when sending authentication requests. The default is Authenticate to first server.", + "type": "string", + "enum": [ + "use-all-servers", + "use-first-server" + ], + "default": "use-first-server" + }, + "debug": { + "description": "Specifies whether to log Syslog debugging information at the LOG_DEBUG level. We do not recommend enabling this setting for normal use. The default is Disabled.", + "type": "boolean", + "default": false + }, + "encryption": { + "description": "Specifies whether to use encryption of TACACS+ packets. The default is Enabled.", + "type": "boolean", + "default": true + }, + "protocol": { + "description": "Specifies the protocol associated with the value specified in Service Name, which is a subset of the associated service being used for client authorization or system accounting. You can use following values: lcp, ip, ipx, atalk, vines, lat, xremote, tn3270, telnet, rlogin, pad, vpdn, ftp, http, deccp, osicp, and unknown. Note that the majority of TACACS+ implementations are of protocol type ip, so try that first.", + "type": "string", + "enum": [ + "lcp", + "ip", + "ipx", + "atalk", + "vines", + "lat", + "xremote", + "tn3270", + "telnet", + "rlogin", + "pad", + "vpdn", + "ftp", + "http", + "deccp", + "osicp", + "unknown" + ] + }, + "secret": { + "description": "Type the secret key used to encrypt and decrypt packets sent or received from the server. Do not use the pound sign ( # ) in the secret for TACACS+ servers.", + "type": "string" + }, + "servers": { + "description": "Specifies a list of the IPv4 addresses for servers using the Terminal Access Controller Access System (TACACS)+ protocol with which the system communicates to obtain authorization data. For each address, an alternate TCP port number may be optionally specified by entering the address in the format address:port. If no port number is specified, the default port 49 is used.", + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "service": { + "description": "Specifies the name of the service that the user is requesting to be authorized to use. Identifying what the user is asking to be authorized for, enables the TACACS+ server to behave differently for different types of authorization requests. You can use following values: slip, ppp, arap, shell, tty-daemon, connection, system, and firewall. Specifying this setting is required. Note that the majority of TACACS+ implementations are of service type ppp, so try that first.", + "type": "string", + "enum": [ + "slip", + "ppp", + "arap", + "shell", + "tty-daemon", + "connection", + "system", + "firewall" + ] + } + } + }, + "ldap": { + "description": "Remote LDAP authentication info", + "type": "object", + "required": ["servers"], + "properties": { + "bindDn": { + "description": "Distinguished name of the server account. If server is a Microsoft Windows Active Directory server, the name must be an email address", + "type": "string" + }, + "bindPassword": { + "description": "Password for the server account", + "type": "string" + }, + "bindTimeout": { + "description": "Timeout limit in seconds to bind to remote authentication server", + "type": "integer", + "minimum": 0, + "maximum": 4294967295, + "default": 30 + }, + "checkBindPassword": { + "description": "Confirms the password for the server account", + "type": "boolean", + "default": false + }, + "checkRemoteRole": { + "description": "Verifies a user's group membership based on the remote-role definition, formatted as *member*of=\"group-dn\"", + "type": "boolean", + "default": false + }, + "filter": { + "description": "Filter used for authorizing client traffic", + "type": "string" + }, + "groupDn": { + "description": "Group distinguished name for authorizing client traffic", + "type": "string" + }, + "groupMemberAttribute": { + "description": "Group member attribute for authorizing client traffic", + "type": "string" + }, + "idleTimeout": { + "description": "Connection timeout limit in seconds", + "type": "integer", + "minimum": 0, + "maximum": 4294967295, + "default": 3600 + }, + "ignoreAuthInfoUnavailable": { + "description": "Ignores authentication information if not available", + "type": "boolean", + "default": false + }, + "ignoreUnknownUser": { + "description": "Ignores a user that is unknown", + "type": "boolean", + "default": false + }, + "loginAttribute": { + "description": "Logon attribute. If server is a Microsoft Windows Active Directory server, the value must be the account name \"samaccountname\"", + "type": "string" + }, + "port": { + "description": "Port number for the LDAP service", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 389 + }, + "referrals": { + "description": "Specifies whether automatic referral chasing should be enabled. This is for BIG-IP 15.1+", + "type": "boolean", + "default": true + }, + "searchScope": { + "description": "Level of remote server's directory to search for user authentication, either base object, one level, or subtree", + "type": "string", + "enum": ["base", "one", "sub"], + "default": "sub" + }, + "searchBaseDn": { + "description": "Search base distinguished name", + "type": "string" + }, + "searchTimeout": { + "description": "Search timeout limit in seconds", + "type": "integer", + "minimum": 0, + "maximum": 4294967295, + "default": 30 + }, + "servers": { + "description": "IP addresses or hostnames of the remote authentication servers.", + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "ssl": { + "description": "Enables SSL", + "type": "string", + "enum": [ "enabled", "disabled", "start-tls" ], + "default": "disabled" + }, + "sslCaCert": { + "description": "SSL certificate issued by a certificate authority", + "allOf": [ + { "$ref": "definitions.schema.json#/definitions/pkiCertificate" }, + { "not": { "required": ["privateKey"] } } + ] + }, + "sslCheckPeer": { + "description": "Specifies whether the system checks an SSL peer", + "type": "boolean", + "default": false + }, + "sslCiphers": { + "description": "Specifies SSL ciphers", + "$comment": "References: https://support.f5.com/csp/article/K13163 https://support.f5.com/csp/article/K97098157 https://support.f5.com/csp/article/K86554600", + "type": "array", + "items": { + "type": "string", + "enum": [ + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES128-CBC-SHA", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-RSA-AES256-CBC-SHA", + "ECDHE-RSA-AES256-SHA384", + "ECDHE-RSA-CHACHA20-POLY1305-SHA256", + "ECDH-RSA-AES128-GCM-SHA256", + "ECDH-RSA-AES128-SHA256", + "ECDH-RSA-AES128-SHA", + "ECDH-RSA-AES256-GCM-SHA384", + "ECDH-RSA-AES256-SHA384", + "ECDH-RSA-AES256-SHA", + "AES128-GCM-SHA256", + "AES128-SHA", + "AES128-SHA256", + "AES256-GCM-SHA384", + "AES256-SHA", + "AES256-SHA256", + "CAMELLIA128-SHA", + "CAMELLIA256-SHA", + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-AES128-SHA", + "ECDHE-ECDSA-AES128-SHA256", + "ECDHE-ECDSA-AES256-GCM-SHA384", + "ECDHE-ECDSA-AES256-SHA", + "ECDHE-ECDSA-AES256-SHA384", + "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256", + "ECDH-ECDSA-AES128-GCM-SHA256", + "ECDH-ECDSA-AES128-SHA", + "ECDH-ECDSA-AES128-SHA256", + "ECDH-ECDSA-AES256-GCM-SHA384", + "ECDH-ECDSA-AES256-SHA", + "ECDH-ECDSA-AES256-SHA384", + "DHE-RSA-AES128-GCM-SHA256", + "DHE-RSA-AES128-SHA", + "DHE-RSA-AES128-SHA256", + "DHE-RSA-AES256-GCM-SHA384", + "DHE-RSA-AES256-SHA", + "DHE-RSA-AES256-SHA256", + "DHE-RSA-CAMELLIA128-SHA", + "DHE-RSA-CAMELLIA256-SHA", + "DHE-DSS-AES128-GCM-SHA256", + "DHE-DSS-AES128-SHA", + "DHE-DSS-AES128-SHA256", + "DHE-DSS-AES256-GCM-SHA384", + "DHE-DSS-AES256-SHA", + "DHE-DSS-AES256-SHA256", + "DHE-DSS-CAMELLIA128-SHA", + "DHE-DSS-CAMELLIA256-SHA", + "ADH-AES128-GCM-SHA256", + "ADH-AES128-SHA", + "ADH-AES256-GCM-SHA384", + "ADH-AES256-SHA", + "ECDHE-RSA-DES-CBC3-SHA", + "ECDH-RSA-DES-CBC3-SHA", + "DES-CBC3-SHA", + "ECDHE-ECDSA-DES-CBC3-SHA", + "ECDH-ECDSA-DES-CBC3-SHA", + "DHE-RSA-DES-CBC3-SHA", + "ADH-DES-CBC3-SHA", + "DHE-RSA-DES-CBC-SHA", + "DES-CBC-SHA", + "ADH-DES-CBC-SHA", + "RC4-SHA", + "RC4-MD5", + "ADH-RC4-MD5", + "EXP1024-DES-CBC-SHA", + "EXP1024-RC4-SHA", + "EXP-RC4-MD5", + "EXP-DES-CBC-SHA", + "TLS13-AES128-GCM-SHA256", + "TLS13-AES256-GCM-SHA384", + "TLS13-CHACHA20-POLY1305-SHA256", + "NULL-SHA", + "NULL-MD5" + ] + }, + "default": [] + }, + "userTemplate": { + "description": "Specifies a user template for the LDAP application to use for authentication.", + "type": "string" + }, + "version": { + "description": "Specifies the version number of the LDAP application.", + "type": "integer", + "minimum": 2, + "maximum": 3, + "default": 3 + } + }, + "additionalProperties": false + } + } +} diff --git a/src/schema/1.40.0/base.schema.json b/src/schema/1.40.0/base.schema.json new file mode 100644 index 00000000..65a855b6 --- /dev/null +++ b/src/schema/1.40.0/base.schema.json @@ -0,0 +1,286 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/base.schema.json", + "title": "F5 BIG-IP Declarative Onboarding base declaration", + "description": "Top level schema for onboarding a BIG-IP.", + "type": "object", + "required": ["schemaVersion", "class"], + "properties": { + "schemaVersion": { + "description": "Version of BIG-IP Declarative Onboarding schema this declaration uses.", + "type": "string", + "enum": [ + "1.40.0", + "1.39.0", + "1.38.0", + "1.37.0", + "1.36.0", + "1.35.0", + "1.34.0", + "1.33.0", + "1.32.0", + "1.31.0", + "1.30.0", + "1.29.0", + "1.28.0", + "1.27.0", + "1.26.0", + "1.25.0", + "1.24.0", + "1.23.0", + "1.22.0", + "1.21.0", + "1.20.0", + "1.19.0", + "1.18.0", + "1.17.0", + "1.16.0", + "1.15.0", + "1.14.0", + "1.13.0", + "1.12.0", + "1.11.1", + "1.11.0", + "1.10.0", + "1.9.0", + "1.8.0", + "1.7.0", + "1.6.1", + "1.6.0", + "1.5.1", + "1.5.0", + "1.4.1", + "1.4.0", + "1.3.0", + "1.2.0", + "1.1.0", + "1.0.0" + ] + }, + "class": { + "description": "Indicates this JSON document is a Device declaration", + "type": "string", + "const": "Device" + }, + "$schema": { + "description": "URL of schema against which to validate. Used by validation in your local environment only (via Visual Studio Code, for example)", + "type": "string", + "format": "uri" + }, + "async": { + "description": "Tells the API to return a 202 HTTP status before processing is complete. User must then poll for status.", + "type": "boolean", + "default": false + }, + "webhook": { + "description": "URL to post results to", + "type": "string", + "format": "uri" + }, + "label": { + "description": "Optional friendly name for this declaration", + "type": "string" + }, + "Credentials": { + "description": "Credentials which can be referenced from other parts of the declaration or the remote wrapper.", + "type": "array", + "items": { + "type": "object", + "properties": { + "username": { + "description": "Username of principal authorized to modify configuration of device (may not include the character ':'). NOTE: this is generally not required to configure 'localhost' because client authentication and authorization precede invocation of DO. It is also not required for any host if you populate tokens", + "type": "string", + "pattern": "^[^:]{0,254}$" + }, + "password": { + "description": "Password for username account. This is generally not required to configure 'localhost' and is not required when you populate tokens", + "type": "string", + "pattern": "^.{0,254}$" + }, + "tokens": { + "description": "One or more HTTP headers (each a property, like 'X-F5-Auth-Token': 'ABCABC') you want to send with queries to the device management service as authentication/authorization tokens", + "type": "object", + "patternProperties": { + "^[^\\x00-\\x20:\\x7f-\\xff]{1,254}$": { + "type": "string", + "pattern": "^[^\\x00-\\x1f\\x7f-\\xff]*$", + "maxLength": 8192 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "if": { + "required": ["tokens"] + }, + "then": { + "dependencies": { + "username": { + "not": {} + }, + "password": { + "not": {} + } + } + }, + "else": { + "dependencies": { + "tokens": { + "not": {} + } + } + } + } + }, + "Common": { + "description": "Special tenant Common holds objects other tenants can share", + "type": "object", + "required": ["class"], + "propertyNames": { + "pattern": "^[A-Za-z][0-9A-Za-z_.-]*$", + "maxLength": 48 + }, + "properties": { + "class": { + "type": "string", + "const": "Tenant" + }, + "hostname": { + "description": "Hostname to set for the device. Note: If you set the hostname as part of the System class, you CANNOT set a hostname in the Common class (they are mutually exclusive).", + "type": "string", + "format": "hostname" + } + }, + "additionalProperties": { + "properties": { + "class": { + "enum": [ + "Analytics", + "Authentication", + "ConfigSync", + "DagGlobals", + "DbVariables", + "DeviceCertificate", + "DeviceGroup", + "DeviceTrust", + "Disk", + "DNS", + "DNS_Resolver", + "FailoverUnicast", + "FailoverMulticast", + "HTTPD", + "License", + "MAC_Masquerade", + "ManagementIp", + "ManagementIpFirewall", + "ManagementRoute", + "MirrorIp", + "NetAddressList", + "NetPortList", + "NTP", + "PasswordPolicy", + "Provision", + "RemoteAuthRole", + "Route", + "RouteDomain", + "RouteMap", + "RoutingAccessList", + "RoutingAsPath", + "RoutingPrefixList", + "RoutingBGP", + "SelfIp", + "SnmpAgent", + "SnmpCommunity", + "SnmpTrapEvents", + "SnmpTrapDestination", + "SnmpUser", + "SSHD", + "SyslogRemoteServer", + "System", + "TrafficControl", + "Trunk", + "Tunnel", + "User", + "VLAN", + "TrafficGroup", + "GSLBGlobals", + "GSLBDataCenter", + "GSLBServer", + "GSLBMonitor", + "GSLBProberPool", + "FirewallPolicy", + "FirewallAddressList", + "FirewallPortList", + "SecurityAnalytics", + "SecurityWaf" + ] + } + }, + "allOf": [ + { "$ref": "system.schema.json#" }, + { "$ref": "network.schema.json#" }, + { "$ref": "dsc.schema.json#" }, + { "$ref": "analytics.schema.json#" }, + { "$ref": "auth.schema.json#" }, + { "$ref": "gslb.schema.json#" }, + { "$ref": "security.schema.json#" } + ] + }, + "default": { + "class": "Tenant" + } + }, + "controls": { + "description": "Options to control configuration process", + "type": "object", + "properties": { + "class": { + "type": "string", + "const": "Controls" + }, + "dryRun": { + "description": "Boolean that indicates if this declaration will be run as a dry-run. If true, the declaration will NOT make any changes to the system, but will respond with whether or not it would.", + "type": "boolean", + "default": false + }, + "trace": { + "description": "If true, create a detailed trace of the configuration process for subsequent analysis (default false). Warning: trace files may contain sensitive configuration data.", + "type": "boolean", + "default": false + }, + "traceResponse": { + "description": "If true, the response will contain the trace files.", + "type": "boolean", + "default": false + }, + "userAgent": { + "description": "User Agent information to include in TEEM report.", + "type": "string" + } + } + }, + "result": { + "description": "Status of current request. This is set by the system.", + "type": "object", + "readOnly": true, + "required": ["class", "code"], + "properties": { + "class": { + "type": "string", + "const": "Result" + }, + "code": { + "description": "Status code.", + "type": "string", + "enum": ["OK", "ERROR"] + }, + "message": { + "description": "Further detail about the status.", + "type": "string" + } + } + } + }, + "additionalProperties": false +} diff --git a/src/schema/1.40.0/definitions.schema.json b/src/schema/1.40.0/definitions.schema.json new file mode 100644 index 00000000..fc9cb46c --- /dev/null +++ b/src/schema/1.40.0/definitions.schema.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/definitions.schema.json", + "title": "F5 BIG-IP Declarative Onboarding Definitions declaration", + "description": "Shared definitions for onboarding a BIG-IP.", + "type": "object", + "definitions": { + "F5string": { + "description": "String value in base64", + "type": "object", + "properties": { + "base64": { + "description": "Base64-encoded value (in JSON string)", + "type": "string", + "format": "f5base64" + }, + "url": { + "$ref": "#/definitions/Resource_URL" + } + }, + "additionalProperties": false, + "minProperties": 1, + "maxProperties": 1 + }, + "pkiCertificate": { + "description": "PKI certificate with optional chain", + "required": ["certificate"], + "properties": { + "certificate": { + "description": "X.509 public-key certificate", + "allOf": [ + { "$ref": "#/definitions/F5string" } + ], + "f5fetch": "pki-cert" + }, + "privateKey": { + "description": "Private key matching certificate's public key (optional)", + "allOf": [ + { "$ref": "#/definitions/F5string" } + ], + "f5fetch": "pki-key" + } + } + }, + "Label": { + "title": "Label", + "description": "Optional friendly name for this object", + "type": "string", + "format": "f5label" + }, + "Remark": { + "title": "Remark", + "description": "Arbitrary (brief) text pertaining to this object (optional)", + "type": "string", + "format": "f5remark" + }, + "Resource_URL": { + "title": "Resource URL", + "description": "The URL for a required resource", + "type": "string", + "format": "uri" + } + } +} diff --git a/src/schema/1.40.0/do.schema.json b/src/schema/1.40.0/do.schema.json new file mode 100644 index 00000000..d5028769 --- /dev/null +++ b/src/schema/1.40.0/do.schema.json @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/do.schema.json", + "title": "F5 BIG-IP Declarative Onboarding base declaration", + "description": "Schema for onboarding a BIG-IP.", + "type": "object", + "required": ["class"], + "properties": { + "class": { + "description": "Top level class. Indicates whether this is a deployment directly to a BIG-IP or to some other system such as BIG-IQ.", + "enum": [ + "Device", + "DO" + ] + } + }, + "allOf": [ + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Device" } } + }, + "then": { + "description": "Indicates that this is a deployment directly to a BIG-IP.", + "$ref": "base.schema.json#" + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DO" } } + }, + "then": { + "description": "Indicates that this is a deployment through an intermediary like BIG-IQ.", + "$ref": "remote.schema.json#" + } + } + ] +} diff --git a/src/schema/1.40.0/dsc.schema.json b/src/schema/1.40.0/dsc.schema.json new file mode 100644 index 00000000..6d39130e --- /dev/null +++ b/src/schema/1.40.0/dsc.schema.json @@ -0,0 +1,400 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/dsc.schema.json", + "title": "F5 BIG-IP Declarative Onboarding DSC declaration", + "description": "Clustering properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "ConfigSync" } } + }, + "then": { + "required": ["class", "configsyncIp"], + "properties": { + "class": { + "description": "Indicates that this property contains config sync IP configuration.", + "type": "string", + "const": "ConfigSync" + }, + "configsyncIp": { + "description": "ConfigSync IP", + "type": "string", + "anyOf": [ + { "const": "none" }, + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "json-pointer" } + ] + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "FailoverUnicast" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains failover unicast address configuration.", + "type": "string", + "const": "FailoverUnicast" + }, + "address": { + "description": "IP address to listen on for failover heartbeats", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "json-pointer" } + ] + }, + "port": { + "description": "Port to listen on for failover heartbeats. The default is 1026.", + "type": "number", + "minimum": 0, + "maximum": 65535 + }, + "addressPorts": { + "description": "An array of address and port objects, that will create multiple failover unicast objects in the BIG-IP device. This array is mutually exclusive from using the other address and port features. Available in BIG-IP DO 1.15 and later.", + "type": "array", + "items": { + "type": "object", + "required": ["address"], + "properties": { + "address": { + "description": "IP address to listen on for failover heartbeats", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "json-pointer" } + ] + }, + "port": { + "description": "Port to listen on for failover heartbeats", + "type": "number", + "minimum": 0, + "maximum": 65535, + "default": 1026 + } + } + } + } + }, + "additionalProperties": false, + "dependencies": { + "address": { + "properties": { + "port": { + "default": 1026 + } + } + } + }, + "oneOf": [ + { + "required": ["address"], + "not": { "required": ["addressPorts"] } + }, + { + "required": ["addressPorts"], + "allOf": [ + { "not": { "required": ["address"] } }, + { "not": { "required": ["port"] } } + ] + } + ] + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "FailoverMulticast" } } + }, + "then": { + "required": ["class", "interface", "address", "port"], + "properties": { + "class": { + "description": "Indicates that this property contains multicast failover configuration.", + "type": "string", + "const": "FailoverMulticast" + }, + "interface": { + "description": "Specifies the interface name used for the failover multicast IP address. Specifying 'none' (the default) here disables Failover Multicast on the BIG-IP.", + "type": "string", + "default": "none" + }, + "address": { + "description": "IP address to listen on for multicast failover. This address cannot have a CIDR.", + "type": "string", + "default": "any6" + }, + "port": { + "description": "Port to listen on for failover heartbeats.", + "type": "number", + "minimum": 0, + "maximum": 65535, + "default": 0 + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DeviceGroup" } } + }, + "then": { + "required": ["class", "type", "owner"], + "properties": { + "class": { + "description": "Indicates that this property contains device group configuration.", + "type": "string", + "const": "DeviceGroup" + }, + "type": { + "description": "Type of the device group", + "type": "string", + "enum": ["sync-failover", "sync-only"] + }, + "owner": { + "description": "Owning device. Config will be pushed from this device. If this is present, device group will only be created if the current device is the owner. If not present, device group will be created if it does not exist", + "type": "string", + "anyOf": [ + { "format": "hostname" }, + { "format": "json-pointer" }, + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "members": { + "description": "Members to add to the device group if they are already in the trust domain", + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ] + } + }, + "autoSync": { + "description": "Whether or not the device group should auto sync", + "type": "boolean", + "default": false + }, + "saveOnAutoSync": { + "description": "Whether or not the device group should save on auto sync", + "type": "boolean", + "default": false + }, + "networkFailover": { + "description": "Whether or not the device group supports network failover", + "type": "boolean", + "default": false + }, + "asmSync": { + "description": "Whether or not the device group should sync ASM properties", + "type": "boolean", + "default": false + }, + "fullLoadOnSync": { + "description": "Whether or not the device group should do a full load on sync", + "type": "boolean", + "default": false + } + }, + "if": { + "required": ["class"], + "properties": { "type": { "const": "sync-failover" } } + }, + "then": { + "if": { + "required": ["autoSync"], + "properties": { "autoSync": { "const": true } } }, + "then": { + "properties": { + "fullLoadOnSync": { + "const": false + } + } + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DeviceTrust" } } + }, + "then": { + "required": ["class", "localUsername", "localPassword", "remoteHost", "remoteUsername", "remotePassword"], + "properties": { + "class": { + "description": "Indicates that this property contains device trust configuration.", + "type": "string", + "const": "DeviceTrust" + }, + "localUsername": { + "description": "The username for the local device", + "type": "string" + }, + "localPassword": { + "description": "The password for the localUsername", + "type": "string" + }, + "remoteHost": { + "description": "The remote hostname or IP address", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" }, + { "format": "json-pointer" } + ] + }, + "remoteUsername": { + "description": "An admin user on the remote host", + "type": "string" + }, + "remotePassword": { + "description": "Password for the remote user in remoteUsername", + "type": "string" + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "TrafficGroup" } } + }, + "then" : { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains Traffic Group configuration.", + "type": "string", + "const": "TrafficGroup" + }, + "autoFailbackEnabled": { + "type": "boolean", + "description": "Specifies whether the traffic group fails back to the default device.", + "default": false + }, + "autoFailbackTime": { + "type": "integer", + "description": "Specifies the time required to fail back.", + "default": 60, + "minimum": 0, + "maximum": 300 + }, + "failoverMethod": { + "type": "string", + "description": "Specifies the method used to decide if the current device needs to failover the traffic-group to another device. If the failover-method is set to ha-order, a list of devices and their respective HA load is used to decide the next one to take over if the current devices fails.", + "enum": [ + "ha-order" + ], + "default": "ha-order" + }, + "haLoadFactor": { + "type": "integer", + "description": "Specifies a number for this traffic group that represents the load this traffic group presents to the system relative to other traffic groups. This allows the failover daemon to load balance the active traffic groups amongst the devices.", + "default": 1, + "minimum": 1, + "maximum": 1000 + }, + "haOrder": { + "type": "array", + "description": "This list of devices specifies the order in which the devices will become active for the traffic group when a failure occurs. This list may contain zero, one, or more entries up to the number of devices in the failover device group.", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "MAC_Masquerade" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains MAC masquerade configuration.", + "type": "string", + "const": "MAC_Masquerade" + }, + "source": { + "description": "MAC address source to use for masquerading.", + "oneOf": [ + { + "type": "object", + "properties": { + "interface": { + "description": "Generate a MAC address from an interface", + "type": "string" + } + }, + "required": ["interface"], + "additionalProperties": false + } + ] + }, + "trafficGroup": { + "description": "Traffic group to apply the MAC masquerade to.", + "type": "string", + "enum": ["traffic-group-local-only", "traffic-group-1"], + "default": "traffic-group-1" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": [ + "class" + ], + "properties": { + "class": { + "const": "MirrorIp" + } + } + }, + "then": { + "required": [ + "class" + ], + "properties": { + "class": { + "description": "Indicates IP addresses to use for connection and persistence mirroring.", + "type": "string", + "const": "MirrorIp" + }, + "primaryIp": { + "description": "IP of primary mirror. Specify 'any6' to disable.", + "type": "string", + "default": "any6" + }, + "secondaryIp": { + "description": "IP of secondary mirror. Specify 'any6' to disable.", + "type": "string", + "default": "any6" + } + }, + "additionalProperties": false + } + } + ] +} diff --git a/src/schema/1.40.0/formats.js b/src/schema/1.40.0/formats.js new file mode 100644 index 00000000..40fbc2cd --- /dev/null +++ b/src/schema/1.40.0/formats.js @@ -0,0 +1,91 @@ +/** + * Copyright 2023 F5 Networks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +/* eslint-disable max-len */ +const IPv4rex = /^(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))(%(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{3}|[1-9]\d{2}|[1-9]?\d))?(\x2f(3[012]|[12]?\d))?$/; + +const IPv6rex = /^(::(([0-9a-f]{1,4}:){0,5}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,4}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}:[0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,3}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){2}::(([0-9a-f]{1,4}:){0,2}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){3}::(([0-9a-f]{1,4}:)?((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){4}::((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){5}::([0-9a-f]{1,4})?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){0,6}::)|(([0-9a-f]{1,4}:){7}[0-9a-f]{1,4})(%(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{3}|[1-9]\d{2}|[1-9]?\d))?(\x2f(12[0-8]|1[01]\d|[1-9]?\d))?$/; + +const IPv4optionalPrefixNoRouteDomainRex = /^(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))?(\x2f(3[012]|[12]?\d))?$/; + +const IPv6optionalPrefixNoRouteDomainRex = /^((::(([0-9a-f]{1,4}:){0,5}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,4}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}:[0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,3}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){2}::(([0-9a-f]{1,4}:){0,2}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){3}::(([0-9a-f]{1,4}:)?((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){4}::((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){5}::([0-9a-f]{1,4})?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){0,6}::)|(([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}))(\x2f(12[0-8]|1[01]\d|[1-9]?\d))?$/; + +const IPv4requiredPrefixNoRouteDomainRex = /^(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))?(\x2f(3[012]|[12]?\d))$/; + +const IPv6requiredPrefixNoRouteDomainRex = /^((::(([0-9a-f]{1,4}:){0,5}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,4}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}:[0-9a-f]{1,4}::(([0-9a-f]{1,4}:){0,3}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){2}::(([0-9a-f]{1,4}:){0,2}((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){3}::(([0-9a-f]{1,4}:)?((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d))))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){4}::((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})|(((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)[.]){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)))?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){5}::([0-9a-f]{1,4})?)|([0-9a-f]{1,4}(:[0-9a-f]{1,4}){0,6}::)|(([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}))(\x2f(12[0-8]|1[01]\d|[1-9]?\d))$/; + +/* eslint-enable max-len */ + +module.exports = { + IPv4optionalPrefixNoRouteDomainRex, + IPv6optionalPrefixNoRouteDomainRex, + IPv4requiredPrefixNoRouteDomainRex, + IPv6requiredPrefixNoRouteDomainRex, + f5ip: (address) => { + const lowerAddress = address.toLowerCase(); + return (!lowerAddress.length + || ((lowerAddress.length > 1) + && (lowerAddress.match(/[^0-9a-f:.%\x2f]/) === null) + && (IPv4rex.test(lowerAddress) || IPv6rex.test(lowerAddress)))); + }, + f5base64: (string) => { + const regex = /^([0-9A-Za-z/+_-]*|[0-9A-Za-z/+_-]+={1,2})$/; + return regex.test(string); + }, + f5bigip: (name) => { + // "f5bigip" ought to match names of BIG-IP configuration + // components. In fact it merely excludes egregious errors. + // It does demand absolute pathnames (i.e., starting with / + // like "/Common/foo") and it forbids space in names + const regex = /^\/[^\s"#'*<>?[-\]{-}]+$/; + return regex.test(name); + }, + ipWithOptionalPrefix: (address) => { + const lowerAddress = address.toLowerCase(); + return (!lowerAddress.length + || ((lowerAddress.length > 1) + && (lowerAddress.match(/[^0-9a-f:.%\x2f]/) === null) + && (IPv4optionalPrefixNoRouteDomainRex.test(lowerAddress) + || IPv6optionalPrefixNoRouteDomainRex.test(lowerAddress)))); + }, + ipWithRequiredPrefix: (address) => { + const lowerAddress = address.toLowerCase(); + return (!lowerAddress.length + || ((lowerAddress.length > 1) + && (lowerAddress.match(/[^0-9a-f:.%\x2f]/) === null) + && (IPv4requiredPrefixNoRouteDomainRex.test(lowerAddress) + || IPv6requiredPrefixNoRouteDomainRex.test(lowerAddress)))); + }, + f5label: (string) => { + // 'f5label' allows 0-64 chars, excluding a few likely to + // cause trouble with string searching, JS, TCL, or HTML + + // eslint-disable-next-line no-control-regex + const regex = /^[^\x00-\x1f\x22#&*<>?\x5b-\x5d`\x7f]{0,64}$/; + return regex.test(string); + }, + f5remark: (string) => { + // 'f5remark' allows 0-64 chars, excluding only control- + // chars, double-quote, and backslash. This is permissive + // enough that you should worry about XSS attacks + + // eslint-disable-next-line no-control-regex + const regex = /^[^\x00-\x1f\x22\x5c\x7f]{0,64}$/; + return regex.test(string); + } +}; diff --git a/src/schema/1.40.0/gslb.schema.json b/src/schema/1.40.0/gslb.schema.json new file mode 100644 index 00000000..493286ee --- /dev/null +++ b/src/schema/1.40.0/gslb.schema.json @@ -0,0 +1,668 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/gslb.schema.json", + "title": "F5 BIG-IP Declarative Onboarding GSLB declaration", + "description": "GSLB properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "GSLBGlobals" } } + }, + "then": { "$ref": "#/definitions/gslbGlobals" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "GSLBDataCenter" } } + }, + "then": { "$ref": "#/definitions/gslbDataCenter" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "GSLBServer" } } + }, + "then": { "$ref": "#/definitions/gslbServer" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "GSLBMonitor" } } + }, + "then": { "$ref": "#/definitions/gslbMonitor" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "GSLBProberPool" } } + }, + "then": { "$ref": "#/definitions/gslbProberPool" } + } + ], + "definitions": { + "gslbGlobals": { + "required": ["class"], + "type": "object", + "description": "GSLB global settings.", + "properties": { + "class": { + "description": "Indicates that this property contains gslb global settings configuration.", + "type": "string", + "const": "GSLBGlobals" + }, + "general": { + "$ref": "#/definitions/generalGlobals" + } + }, + "additionalProperties": false + }, + "generalGlobals": { + "type":"object", + "description": "GSLB general global settings.", + "properties": { + "synchronizationEnabled": { + "description": "Specifies if the system is a member of a synchronization group.", + "type": "boolean", + "default": false + }, + "synchronizationGroupName": { + "description": "Specifies the name of the synchronization group that the system belongs to.", + "type": "string", + "default": "default" + }, + "synchronizationTimeTolerance": { + "description": "Specifies the number of seconds that one system can be out of sync with another in the synchronization group. A value of 0 turns time synchronization off. The values 1-4 are not allowed.", + "type": "integer", + "minimum": 0, + "maximum": 600, + "default": 10, + "not": { + "enum": [1, 2, 3, 4] + } + }, + "synchronizationTimeout": { + "description": "Specifies the number of seconds that the system attempts to sync with the GSLB configuration with a sync group member.", + "type": "integer", + "minimum": 0, + "maximum": 4294967295, + "default": 180 + } + }, + "additionalProperties": false + }, + "gslbDataCenter": { + "required": ["class"], + "description": "Declares a GSLB Data Center configuration", + "type": "object", + "properties": { + "class": { + "type": "string", + "const": "GSLBDataCenter" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "enabled": { + "description": "Specifies whether the data center is enabled or disabled", + "type": "boolean", + "default": true + }, + "location": { + "description": "Specifies the location of the data center", + "type": "string" + }, + "contact": { + "description": "Specifies the name of the administrator or the name of the department that manages the data center", + "type": "string" + }, + "proberPreferred": { + "description": "Specifies the type of prober to use to monitor servers defined in this data center. The default value is inside-data-center. Note: Prober pools are not used by the bigip monitor", + "type": "string", + "enum": [ + "inside-datacenter", "outside-datacenter", "pool" + ], + "default": "inside-datacenter" + }, + "proberFallback": { + "description": "Specifies the type of prober to use to monitor servers defined in this data center when the preferred type is not available. The default value is any-available", + "type": "string", + "enum": [ + "any-available", "inside-datacenter", "none", "outside-datacenter", "pool" + ], + "default": "any-available" + }, + "proberPool": { + "description": "Specifies a prober pool to monitor servers defined in the data center when proberPreferred or proberFallback are a value of pool.", + "type": "string" + } + }, + + "dependencies": { + "proberPool": { + "oneOf": [ + { "properties": { "proberPreferred": { "const": "pool" } } }, + { "properties": { "proberFallback": { "const": "pool" } } } + ] + } + }, + "additionalProperties": false + }, + "gslbServer": { + "required": [ "class", "dataCenter", "devices" ], + "description": "Declares a GSLB server object which contains configuration for a load balancer or a host server", + "type": "object", + "properties": { + "class": { + "description": "Indicates that this property contains GSLB server configuration", + "type": "string", + "const": "GSLBServer" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "enabled": { + "description": "Specifies whether the server is enabled or disabled", + "type": "boolean", + "default": true + }, + "serverType": { + "description": "Specifies the server type. The server type determines the metrics that the system can collect from the server", + "type": "string", + "enum":[ + "bigip", "generic-host" + ], + "default": "bigip" + }, + "proberPreferred": { + "description": "Specifies the type of prober to use to monitor servers defined in this data center. The default value is inherit. Note: Prober pools are not used by the bigip monitor", + "type": "string", + "enum": [ + "inherit", "inside-datacenter", "outside-datacenter", "pool" + ], + "default": "inherit" + }, + "proberFallback": { + "description": "Specifies the type of prober to use to monitor servers defined in this data center when the preferred type is not available. The default value is inherit", + "type": "string", + "enum": [ + "inherit", "any-available", "inside-datacenter", "none", "outside-datacenter", "pool" + ], + "default": "inherit" + }, + "proberPool": { + "description": "Specifies the name of a prober pool to use to monitor this server's resources when either the proberPreferred or proberFallback value is pool", + "type": "string" + }, + "dataCenter": { + "description": "Specifies the GSLB data center to which the server belongs", + "type": "string" + }, + "devices": { + "description": "Specifies the actual device(s) that are represented by this server object", + "type": "array", + "items": { "$ref": "#/definitions/gslbServerDevice" }, + "minItems": 1 + }, + "virtualServers": { + "description": "Specifies the virtual server(s) that are resources on this server object", + "type": "array", + "items": { "$ref": "#/definitions/gslbVirtualServer" } + }, + "virtualServerDiscoveryMode": { + "description": "Specifies virtual server auto-discovery settings. Use 'enabled' (add, modify, delete), 'enabled-no-delete' (add, modify) or the default 'disabled' (manual configuration)", + "type": "string", + "enum": [ + "disabled", + "enabled", + "enabled-no-delete" + ], + "default": "disabled" + }, + "exposeRouteDomainsEnabled": { + "description": "Allows virtual servers from all route domains to be auto-discovered. The default setting is false", + "type": "boolean", + "default": false + }, + "bpsLimit": { + "description": "Specifies the maximum allowable data throughput rate, in bits per second, for the virtual servers on the server. If the network traffic volume exceeds this limit, the system marks the server as unavailable", + "type": "integer", + "default": 0, + "minimum": 0 + }, + "bpsLimitEnabled": { + "description": "Enables or disables the maximum Bits Per Second (BPS) option for the virtual servers on the server. The default value is false (disabled)", + "type": "boolean", + "default": false + }, + "ppsLimit": { + "description": "Specifies the maximum allowable data transfer rate, in packets per second, for the virtual servers on the server. If the network traffic volume exceeds this value, the system marks the server as unavailable", + "type": "integer", + "default": 0, + "minimum": 0 + }, + "ppsLimitEnabled": { + "description": "Enables or disables the maximum Packets Per Second (PPS) option for the virtual servers on the server. The default value is false (disabled)", + "type": "boolean", + "default": false + }, + "connectionsLimit": { + "description": "Specifies the number of current connections allowed for the virtual servers on the server. If the current connections exceed this value, the system marks the server as unavailable", + "type": "integer", + "default": 0, + "minimum": 0 + }, + "connectionsLimitEnabled": { + "description": "Enables or disables the maximum current connections option for the virtual servers on the server. The default value is false (disabled)", + "type": "boolean", + "default": false + }, + "cpuUsageLimit": { + "description": "Specifies the percent of CPU usage. If percent of CPU usage goes above the limit, the system marks the server as unavailable", + "type": "integer", + "minimum": 0, + "default": 0 + }, + "cpuUsageLimitEnabled": { + "description": "Enables or disables the CPU Usage limit option for this pool. The default value is false (disabled)", + "type": "boolean", + "default": false + }, + "memoryLimit": { + "description": "Specifies the available memory in kilobytes required by the virtual servers on the server. If available memory falls below this limit, the system marks the server as unavailable", + "type": "integer", + "minimum": 0, + "default": 0 + }, + "memoryLimitEnabled": { + "description": "Enables or disables the maximum Bits Per Second (BPS) option for this pool. The default value is false (disabled)", + "type": "boolean", + "default": false + }, + "serviceCheckProbeEnabled": { + "description": "Specifies whether this BIG-IP device will be used to conduct a service check probe before traffic will be delegated to it. The default value is (true) enabled ", + "type": "boolean", + "default": true + }, + "pathProbeEnabled": { + "description": "Specifies whether this BIG-IP device will be used to conduct a path probe before traffic will be delegated to it. The default value is (true) enabled ", + "type": "boolean", + "default": true + }, + "snmpProbeEnabled": { + "description": "Specifies whether this BIG-IP device will be used to conduct a SNMP probe before traffic will be delegated to it. The default value is (true) enabled ", + "type": "boolean", + "default": true + }, + "monitors": { + "description": "Specifies the path and name of the health monitors that the system uses to determine whether it can use this server for load balancing", + "type": "array", + "items": { + "type": "string" + } + } + }, + "dependencies": { + "proberPreferred": { + "if": { "properties": { "proberPreferred": { "const": "pool" } } }, + "then": { "required": [ "proberPool" ] } + }, + "proberFallback": { + "if": { "properties": { "proberFallback": { "const": "pool" } } }, + "then": { "required": [ "proberPool" ] } + } + }, + "additionalProperties": false + }, + "gslbServerDevice": { + "description": "Configures a device for the GSLB server", + "type": "object", + "required": [ "address" ], + "properties": { + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "address": { + "type": "string", + "description": " Specifies an external (public) address for the device. If BIG-IP DNS configuration synchronization is enabled and all existing addresses for a device are being replaced, new addresses should be added and synchronized before old addresses are removed, otherwise the changes may fail to synchronize. Alternatively, the address configuration changes can be performed on each BIG-IP DNS system", + "format": "f5ip" + }, + "addressTranslation": { + "type": "string", + "description": "Specifies the internal (private) address that corresponds to the external address", + "format": "f5ip" + } + }, + "additionalProperties": false + }, + "gslbMonitor": { + "description": "Declares a monitor that verifies the availability and/or performance status of a particular protocol, service or application", + "type": "object", + "required": [ "class", "monitorType" ], + "properties": { + "class": { + "type": "string", + "const": "GSLBMonitor" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "monitorType": { + "description": "Specifies the type of monitor", + "type": "string", + "enum": [ "http", "https", "gateway-icmp", "tcp", "udp" ] + }, + "target": { + "description": "Specifies the IP address and service port of the resource that is the destination of this monitor. Format is ip:port", + "type": "string", + "default": "*:*" + }, + "interval": { + "description": "Specifies, in seconds, the frequency at which the system issues the monitor check when either the resource is down or the status of the resource is unknown", + "type": "integer", + "minimum": 0, + "maximum": 86399, + "default": 30 + }, + "timeout": { + "description": "Specifies the number of seconds the target has in which to respond to the monitor request", + "type": "integer", + "minimum": 0, + "maximum": 86400, + "default": 120 + }, + "probeTimeout": { + "description": "Specifies the number of seconds after which the system times out the probe request to the system", + "type": "integer", + "minimum": 0, + "maximum": 86400, + "default": 5 + }, + "ignoreDownResponseEnabled": { + "description": "Specifies whether the monitor immediately marks an object down when it recieves a down response. If enabled, the monitor ignores the down response for the duration of timeout. The default is false (disabled)", + "type": "boolean", + "default": false + }, + "transparent": { + "description": "Enables monitoring of pool members through firewalls. The default value is false (disabled)", + "type": "boolean", + "default": false + } + }, + "allOf": [ + { + "if": { "properties": { "monitorType": { "const": "http" } } }, + "then": { "$ref": "#/definitions/gslbMonitorHTTP" } + }, + { + "if": { "properties": { "monitorType": { "const": "https" } } }, + "then": { "$ref": "#/definitions/gslbMonitorHTTPS" } + }, + { + "if": { "properties": { "monitorType": { "const": "gateway-icmp" } } }, + "then": { "$ref": "#/definitions/gslbMonitorICMP" } + }, + { + "if": { "properties": { "monitorType": { "const": "tcp" } } }, + "then": { "$ref": "#/definitions/gslbMonitorTCP" } + }, + { + "if": { "properties": { "monitorType": { "const": "udp" } } }, + "then": { "$ref": "#/definitions/gslbMonitorUDP" } + } + ] + }, + + "gslbMonitorHTTP": { + "description": "Additional Monitor class properties available when monitorType = http", + "type": "object", + "properties": { + "reverseEnabled": { + "description": "When enabled, a successful check marks the monitored object down instead of up. You can use the Reverse mode only if you configure both the send and receive options", + "type": "boolean", + "default": false + }, + "send": { + "description": "Specifies the text string that the monitor sends to the target object. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "HEAD / HTTP/1.0\\r\\n\\r\\n" + }, + "receive": { + "description": "Specifies the text string that the monitor looks for in the returned resource. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "HTTP/1." + } + } + }, + "gslbMonitorHTTPS": { + "description": "Additional Monitor class properties available when monitorType = https", + "type": "object", + "allOf": [ + { + "properties": { + "ciphers": { + "description": "Ciphersuite selection string", + "type": "string", + "default": "DEFAULT" + }, + "clientCertificate": { + "description": "Pointer to client Certificate declaration, for TLS authentication (optional)", + "type": "string" + } + } + }, + { + "$ref": "#/definitions/gslbMonitorHTTP" + } + ] + }, + "gslbMonitorICMP": { + "description": "Additional Monitor class properties available when monitorType = gateway-icmp", + "type": "object", + "properties": { + "probeInterval": { + "description": "Specifies the frequency at which the BIG-IP system probes the host server", + "type": "integer", + "minimum": 0, + "default": 1 + }, + "probeAttempts": { + "description": "Specifies the number of times the BIG-IP system attempts to probe the host server, after which the BIG-IP system considers the host server down or unavailable", + "type": "integer", + "minimum": 0, + "default": 3 + } + } + }, + "gslbMonitorTCP": { + "description": "Additional Monitor class properties available when monitorType = tcp", + "type": "object", + "properties": { + "reverseEnabled": { + "description": "When enabled, a successful check marks the monitored object down instead of up. You can use the Reverse mode only if you configure both the send and receive options", + "type": "boolean", + "default": false + }, + "send": { + "description": "Specifies the text string that the monitor sends to the target object. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "" + }, + "receive": { + "description": "Specifies the text string that the monitor looks for in the returned resource. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "" + } + } + }, + "gslbMonitorUDP": { + "description": "Additional Monitor class properties available when monitorType = udp", + "type": "object", + "properties": { + "debugEnabled": { + "description": "When enabled, the monitor sends error messages and additional information to a log file created and labeled specifically for this monitor. The default is false (disabled)", + "type": "boolean", + "default": false + }, + "probeAttempts": { + "description": "Specifies the number of times the BIG-IP system attempts to probe the host server, after which the BIG-IP system considers the host server down or unavailable", + "type": "integer", + "minimum": 0, + "default": 3 + }, + "probeInterval": { + "description": "Specifies the frequency at which the BIG-IP system probes the host server", + "type": "integer", + "minimum": 0, + "default": 1 + }, + "reverseEnabled": { + "description": "When enabled, a successful check marks the monitored object down instead of up. You can use the Reverse mode only if you configure both the send and receive options", + "type": "boolean", + "default": false + }, + "send": { + "description": "Specifies the text string that the monitor sends to the target object. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "default send string" + }, + "receive": { + "description": "Specifies the text string that the monitor looks for in the returned resource. If you do not specify a value for both the send and receive options, the monitor performs a simple service check and connect only", + "type": "string", + "default": "" + } + } + }, + "gslbProberPool": { + "description": "Declares a pool of BIG-IP devices that will monitor server resources for health and performance. Note: Prober pools are not used by the bigip monitor", + "type": "object", + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains GSLB Prober Pool configuration", + "type": "string", + "const": "GSLBProberPool" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "enabled": { + "description": "Specifies whether this pool is available for conducting probes", + "type": "boolean", + "default": true + }, + "lbMode": { + "description": "Specifies the load balancing mode that the system uses to select the members of this pool", + "type": "string", + "enum": [ + "global-availability", + "round-robin" + ], + "default": "global-availability" + }, + "members": { + "description": "Specifies the members of the prober pool", + "type": "array", + "items": { + "$ref": "#/definitions/gslbProberPoolMember" + } + } + }, + "additionalProperties": false + }, + "gslbProberPoolMember": { + "description": "Declares member of the GSLB prober pool", + "type": "object", + "required": [ "server" ], + "properties": { + "server": { + "description": "Specifies the GSLB Server name of the pool member", + "type": "string" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "enabled": { + "description": "Specifies whether the server can be used as a member of a prober pool", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + }, + "gslbVirtualServer": { + "description": "Declares virtual server resource for the GSLB server", + "type": "object", + "required": ["address"], + "properties": { + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "enabled": { + "description": "Specifies whether the virtual server is enabled or disabled", + "type": "boolean", + "default": true + }, + "port": { + "description": "Specifies the L4 port for the service (like 443 for HTTPS)", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "address": { + "description": "Specifies the IP address for the virtual server", + "type": "string", + "format": "f5ip" + }, + "addressTranslation": { + "description": "Specifies the public address that this virtual server translates into when the GSLB provider communicates between the network and the Internet", + "type": "string", + "format": "f5ip" + }, + "addressTranslationPort": { + "description": "Specifies the translation port number for the virtual server", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "monitors": { + "description": "Specifies the health monitors that the system uses to determine whether it can use this linked virtual server for load balancing", + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "description": "Specifies the name of the virtual server", + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/src/schema/1.40.0/network.schema.json b/src/schema/1.40.0/network.schema.json new file mode 100644 index 00000000..686b069a --- /dev/null +++ b/src/schema/1.40.0/network.schema.json @@ -0,0 +1,1513 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/network.schema.json", + "title": "F5 BIG-IP Declarative Onboarding network declaration", + "description": "Network properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Trunk" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains Trunk configuration.", + "type": "string", + "const": "Trunk" + }, + "distributionHash": { + "description": "Specifies the basis for the hash that the system uses as the frame distribution algorithm. Choices are 'dst-mac' (use the destination MAC addresses), 'src-dist-mac' (use the source, destination, and MAC addresses), or 'src-dst-ipport' (use the source and destination IP addresses and ports).", + "type": "string", + "enum": ["dst-mac", "src-dst-ipport", "src-dst-mac"], + "default": "dst-mac" + }, + "interfaces": { + "description": "Interfaces for the Trunk. The number of interfaces used is recommended to be a power of 2 (for example 2, 4, or 8). Interfaces must be untagged.", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "lacpEnabled": { + "description": "Specifies, when true, that the system supports the link aggregation control protocol (LACP), which monitors the trunk by exchanging control packets over the member links to determine the health of the links.", + "type": "boolean", + "default": false + }, + "lacpMode": { + "description": "Specifies the operation mode for LACP if the lacp option is enabled for the trunk. The values are 'active' (specifies the system periodically transmits LACP packets, regardless of the control value of the peer system) and 'passive' (specifies the system periodically transmits LACP packets, unless the control value of the peer system is active).", + "type": "string", + "enum": ["active", "passive"], + "default": "active" + }, + "lacpTimeout": { + "description": "Specifies the rate at which the system sends the LACP control packets.", + "type": "string", + "enum": ["long", "short"], + "default": "long" + }, + "linkSelectPolicy": { + "description": "Sets the LACP policy that the trunk uses to determine which member link (interface) can handle new traffic.", + "type": "string", + "enum": ["auto", "maximum-bandwidth"], + "default": "auto" + }, + "qinqEthertype": { + "description": "Specifies the ether-type value used for the packets handled on this trunk when it is a member in a QinQ vlan.", + "type": "string", + "pattern": "^0x[a-fA-F0-9]{4}$", + "default": "0x8100" + }, + "spanningTreeEnabled": { + "description": "Enables the spanning tree protocols (STP).", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "VLAN" } } + }, + "then": { + "required": ["class", "interfaces"], + "properties": { + "class": { + "description": "Indicates that this property contains VLAN configuration.", + "type": "string", + "const": "VLAN" + }, + "mtu": { + "description": "MTU for the VLAN.", + "type": "integer", + "minimum": 576, + "maximum": 9198, + "default": 1500 + }, + "tag": { + "description": "Tag for the VLAN.", + "type": "integer", + "minimum": 1, + "maximum": 4094 + }, + "interfaces": { + "description": "Interfaces for the VLAN.", + "type": "array", + "items": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "description": "Name of the interface.", + "type": "string" + }, + "tagged": { + "description": "Whether or not the interface is tagged. Default is true if a VLAN tag is provided, otherwise false.", + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "autoLastHop": { + "description": "When enabled, allows the system to send return traffic to the MAC address that transmitted the request, even if the routing table points to a different network or interface. As a result, the system can send return traffic to clients even when there is no matching route. Settings are default (inherited global setting), enabled, and disabled.", + "type": "string", + "enum": ["default", "enabled", "disabled"], + "default": "default" + }, + "cmpHash": { + "description": "Specifies how the traffic on the VLAN will be disaggregated.", + "type": "string", + "enum": ["default", "dst-ip", "src-ip"], + "default": "default" + }, + "failsafeEnabled": { + "description": "Enables a fail-safe mechanism that causes the active cluster to fail over to a redundant cluster when loss of traiffic is detected on a VLAN", + "type": "boolean", + "default": false + }, + "failsafeAction": { + "description": "Specifies the action for the system to take when the fail-safe mechanism is triggered", + "type": "string", + "enum": ["failover", "failover-restart-tm", "reboot", "restart-all"], + "default": "failover-restart-tm" + }, + "failsafeTimeout": { + "description": "Specifies the number of seconds that an active unit can run without detecting network traffic on this VLAN before starting a failover", + "type": "integer", + "minimum": 10, + "maximum": 3600, + "default": 90 + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "FirewallPolicy" } } + }, + "then": { "$ref": "#/definitions/firewallPolicy" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "FirewallAddressList" } } + }, + "then": { "$ref": "#/definitions/firewallAddressList" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "FirewallPortList" } } + }, + "then": { "$ref": "#/definitions/firewallPortList" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "NetAddressList" } } + }, + "then": { "$ref": "#/definitions/netAddressList" } + }, + { + "if": { + "required": ["class"], + "type": "object", + "properties": { "class": { "const": "NetPortList" } } + }, + "then": { "$ref": "#/definitions/netPortList" } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SelfIp" } } + }, + "then": { + "required": ["class", "address", "vlan"], + "properties": { + "class": { + "description": "Indicates that this property contains Self IP configuration.", + "type": "string", + "const": "SelfIp" + }, + "address": { + "description": "IP address.", + "type": "string", + "format": "f5ip" + }, + "trafficGroup": { + "description": "Traffic group for the Self IP.", + "type": "string", + "enum": ["traffic-group-local-only", "traffic-group-1"], + "default": "traffic-group-local-only" + }, + "vlan": { + "description": "VLAN or Tunnel for the self IP.", + "type": "string" + }, + "allowService": { + "description": "Which services (ports) to allow on the self IP. Value should be 'all', 'none', 'default', or array of ''. NOTE: The default value is not recommended and a value of 'none' should be used if possible.", + "oneOf": [ + { + "type": "string", + "enum": ["all", "none", "default"] + }, + { + "type": "array", + "items": { + "type": "string", + "pattern": "(\\w+:\\d+|default)" + } + } + ], + "default": "none" + }, + "enforcedFirewallPolicy": { + "description": "Specifies an enforced firewall policy on the self IP.", + "type": "string" + }, + "stagedFirewallPolicy": { + "description": "Specifies a staged firewall policy on the self IP.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DNS_Resolver" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains DNS Resolver configuration.", + "type": "string", + "const": "DNS_Resolver" + }, + "answerDefaultZones": { + "description": "Specifies whether the resolver answers queries for default zones: localhost, reverse 127.0.0.1, ::1, and AS112 zones.", + "type": "boolean", + "default": false + }, + "cacheSize": { + "description": "Specifies the maximum cach size in bytes of the DNS Resolver object", + "type": "integer", + "minimum": 10, + "maximum": 9437184, + "default": 5767168 + }, + "forwardZones": { + "description": "Forward zones on a DNS Resolver. A given zone name should only use the symbols allowed for a fully qualified domain name (FQDN), namely ASCII letters a through z, digits 0 through 9, hyphen, nad period. For example site.example.com would be a valid zone name. A DNS Resolver configured with a forward zone will forward any queries that resulted in a cache-miss and which also match a configured zone name, to the nameserver specified on the zone.", + "type": "array", + "items": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "description": "Name of a forward zone.", + "type": "string", + "anyOf": [ + { + "format": "hostname" + }, + { + "pattern": "^\\.$" + } + ] + }, + "nameservers": { + "description": "Specifies the IP address and service port of a recursive nameserver that answers DNS queries when the response cannot be found in the internal DNS resolver cache. Enter each address in the format address:port (IPv4) or addrss.port (IPv6). The port is usually 53.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "randomizeQueryNameCase": { + "description": "Specifies whether the resolver randomizes the case of query names.", + "type": "boolean", + "default": true + }, + "routeDomain": { + "description": "Specifies the name of the route domain the resolver uses for outbound traffic.", + "type": "string", + "default": "0" + }, + "useIpv4": { + "description": "Specifies whether the resolver sends DNS queries to IPv4", + "type": "boolean", + "default": true + }, + "useIpv6": { + "description": "Specifies whether the resolver sends DNS queries to IPv6", + "type": "boolean", + "default": true + }, + "useTcp": { + "description": "Specifies whether the resolver sends DNS queries over TCP", + "type": "boolean", + "default": true + }, + "useUdp": { + "description": "Specifies whether the resolver sends DNS queries over UDP", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Route" } } + }, + "then": { + "properties": { + "class": { + "description": "Indicates that this property contains Route configuration.", + "type": "string", + "const": "Route" + }, + "gw": { + "description": "Gateway for the route.", + "type": "string", + "format": "f5ip" + }, + "network": { + "description": "IP address/netmask for route", + "type": "string", + "anyOf": [ + { "format": "f5ip" }, + { "enum": ["default", "default-inet6"]} + ], + "default": "default" + }, + "mtu": { + "description": "MTU for the route.", + "type": "integer", + "minimum": 0, + "maximum": 9198 + }, + "target": { + "description": "The VLAN or Tunnel for the Route.", + "type": "string", + "minLength": 0 + }, + "localOnly": { + "description": "A boolean to indicate if the Route should be added to the LOCAL_ONLY partition. 'Across Network' clusters in AWS require this partition to be configured.", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false, + "anyOf": [ + { + "required": ["class", "gw"] + }, + { + "required": ["class", "target"] + } + ] + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RouteDomain" } } + }, + "then": { + "required": ["class", "id"], + "properties": { + "class": { + "description": "Indicates that this property contains Route Domain configuration.", + "type": "string", + "const": "RouteDomain" + }, + "id": { + "description": "Specifies a unique numeric identifier for the route domain.", + "type": "integer", + "minimum": 0, + "maximum": 65534 + }, + "parent": { + "description": "Specifies the route domain the system searches when it cannot find a route in the configured domain.", + "type": "string" + }, + "bandWidthControllerPolicy": { + "description": "Specifies the bandwidth controller policy for the route domain.", + "type": "string" + }, + "connectionLimit": { + "description": "The connection limit for the route domain.", + "type": "integer", + "minimum": 0, + "maximum": 4294967295, + "default": 0 + }, + "flowEvictionPolicy": { + "description": "Specifies a flow eviction policy for the route domain to use.", + "type": "string" + }, + "ipIntelligencePolicy": { + "description": "Specifies an IP intelligence policy for the route domain to use.", + "type": "string" + }, + "enforcedFirewallPolicy": { + "description": "Specifies an enforced firewall policy on the route domain.", + "type": "string" + }, + "stagedFirewallPolicy": { + "description": "Specifies a staged firewall policy on the route domain.", + "type": "string" + }, + "securityNatPolicy": { + "description": "Specifies the security NAT policy for the route domain.", + "type": "string" + }, + "servicePolicy": { + "description": "Specifies the service policy for the route domain.", + "type": "string" + }, + "strict": { + "description": "Determines whether a connection can span route domains.", + "type": "boolean", + "default": true + }, + "routingProtocols": { + "description": "Specifies routing protocols for the system to use in the route domain.", + "type": "array", + "items": { + "type": "string", + "enum": ["BFD", "BGP", "IS-IS", "OSPFv2", "OSPFv3", "PIM", "RIP", "RIPng"] + } + }, + "vlans": { + "description": "Specifies VLANS for the system to use in the route domain.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DagGlobals" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains DAG Globals configuration.", + "type": "string", + "const": "DagGlobals" + }, + "icmpHash": { + "description": "Specifies ICMP hash for ICMP echo request and ICMP echo reply in SW DAG.", + "type": "string", + "enum": ["icmp", "ipicmp"], + "default": "icmp" + }, + "ipv6PrefixLength": { + "description": "Specifies whether SPDAG or IPv6 prefix DAG should be used to disaggregate IPv6 traffic when vlan cmp hash is set to src-ip or dst-ip.", + "type": "integer", + "default": 128, + "minimum": 0, + "maximum": 128 + }, + "roundRobinMode": { + "description": "Specifies whether the round robin disaggregator (DAG) on a blade can disaggregate packets to all the TMMs in the system or only to the TMMs local to the blade.", + "type": "string", + "enum": ["global", "local"], + "default": "global" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Tunnel" } } + }, + "then": { + "required": ["class", "tunnelType"], + "properties": { + "class": { + "description": "Indicates that this property contains Tunnel configuration.", + "type": "string", + "const": "Tunnel" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "tunnelType": { + "description": "Specifies the profile that you want to associate with the Tunnel. Note: As of 1.36.0, when creating a VXLAN Tunnel, accept-ip-options in traffic controls will no longer default to true. Instead it will remain the same or be set to the value in the declaration.", + "type": "string", + "enum": ["geneve", "gre", "tcp-forward", "vxlan"] + }, + "mtu": { + "description": "Specifies the maximum transmission unit of the Tunnel.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "usePmtu": { + "description": "Enable or disable the Tunnel to use Path MTU information provided by ICMP NeedFrag error messages.", + "type": "boolean", + "default": true + }, + "typeOfService": { + "description": "Specifies a value for insertion into the Type of Service octet within the IP header of the encapsulating header of transmitted packets.", + "oneOf": [ + { + "type": "string", + "enum": ["preserve"] + }, + { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + ], + "default": "preserve" + }, + "autoLastHop": { + "description": "Specifies that packets are returned to the MAC address from which they were sent when enabled. The default setting specifies that the system uses the default route to send back the request.", + "type": "string", + "enum": [ + "default", + "enabled", + "disabled" + ], + "default": "default" + }, + "key": { + "description": "When applied to a GRE tunnel, this value specifies an optional field in the GRE header, used to authenticate the source of the packet. When applied to a VXLAN or Geneve tunnel, this value specifies the Virtual Network Identifier (VNI). When applied to an NVGRE tunnel, this value specifies the Virtual Subnet Identifier (VSID).", + "type": "integer", + "minimum": 0, + "default": 0 + }, + "localAddress": { + "description": "Specifies the IP address of the local endpoint of the tunnel.", + "type": "string", + "anyOf": [ + { "enum": ["any", "any6"] }, + { "format": "f5ip" } + ], + "default": "any6" + }, + "remoteAddress": { + "description": "Specifies the IP address of the remote endpoint of the tunnel.", + "type": "string", + "anyOf": [ + { "enum": ["any", "any6"] }, + { "format": "f5ip" } + ], + "default": "any6" + }, + "secondaryAddress": { + "description": "Specifies a non-floating IP address for the tunnel, to be used with host-initiated traffic.", + "type": "string", + "anyOf": [ + { "enum": ["any", "any6"] }, + { "format": "f5ip" } + ], + "default": "any6" + }, + "mode": { + "description": "Specifies how the tunnel carries traffic.", + "type": "string", + "enum": ["bidirectional", "inbound", "outbound"], + "default": "bidirectional" + }, + "transparent": { + "description": "Specifies that the tunnel operates in transparent mode. When enabled, you can inspect and manipulate the encapsulated traffic flowing through the BIG-IP system.", + "type": "boolean", + "default": false + }, + "trafficGroup": { + "description": "Specifies the traffic group to associate with the tunnel.", + "type": "string", + "default": "none" + } + }, + "allOf": [ + { + "if": { + "required": ["transparent", "trafficGroup"], + "properties": { "transparent": { "const": true } } + }, + "then": { + "properties": { + "trafficGroup": { "const": "none" } + } + } + }, + { + "if": { + "required": ["tunnelType"], + "properties": { "tunnelType": { "const": "geneve" } } + }, + "then": { + "properties": { + "mode": { "const": "bidirectional" }, + "remoteAddress": { "enum": ["any", "any6"] } + } + } + }, + { + "if": { + "required": ["tunnelType"], + "properties": { "tunnelType": { "const": "vxlan" } } + }, + "then": { + "properties": { + "defaultsFrom": { + "description": "Specifies the existing profile from which the system imports settings for the new profile. Default value is vxlan. Can NOT default from itself.", + "type": "string", + "default": "vxlan" + }, + "port": { + "description": "Specifies the local port for receiving VXLAN packets. The default is 4789.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 4789 + }, + "floodingType": { + "description": "Specifies the flooding type to use to transmit multicast, broadcast, and unknown destination frames. The default is multicast.", + "type": "string", + "enum": ["none", "multicast", "multipoint", "replicator"], + "default": "multicast" + }, + "encapsulationType": { + "description": "Specifies whether the VXLAN header is formatted according to RFC 7348 (vxlan) or with the Generic Protocol Extension (vxlan-gpe). The default is vxlan.", + "type": "string", + "enum": ["vxlan", "vxlan-gpe"], + "default": "vxlan" + } + } + } + } + ] + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RoutingAsPath" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains routing AS path configuration.", + "type": "string", + "const": "RoutingAsPath" + }, + "entries": { + "description": "An array that holds action and regex objects", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "integer", + "description": "Name of the entity" + }, + "regex": { + "type": "string", + "description": "A regex string" + } + }, + "required": ["name", "regex"], + "additionalProperties": false + }, + "default": [] + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RoutingAccessList" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains routing access list configuration.", + "type": "string", + "const": "RoutingAccessList" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "entries": { + "description": "An array that holds sources and destinations.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "integer", + "description": "Name of the entity identified as an integer" + }, + "action": { + "type": "string", + "description": "Permit or deny access", + "enum": [ + "permit", + "deny" + ] + }, + "destination": { + "description": "IPv4 or IPv6 address or address range. Specify either [address] or [address/prefixlength].", + "type": "string", + "format": "ipWithOptionalPrefix", + "default": "::" + }, + "exactMatchEnabled": { + "description": "Perform exact matching. A single entry with exactMatchEnabled true disallows any entry to have a non-default destination.", + "type": "boolean", + "default": false + }, + "source": { + "description": "IPv4 or IPv6 address or address range. Specify either [address] or [address/prefixlength].", + "type": "string", + "format": "ipWithOptionalPrefix", + "default": "::" + } + }, + "required": ["name", "action"], + "additionalProperties": false + }, + "default": [] + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RoutingPrefixList" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains routing prefix list configuration.", + "type": "string", + "const": "RoutingPrefixList" + }, + "entries": { + "description": "An array that holds action, prefix, and prefixLengthRange.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "integer", + "description": "Name of the entity" + }, + "action": { + "type": "string", + "description": "An action to take", + "enum": [ + "permit", + "deny" + ] + }, + "prefix": { + "type": "string", + "description": "Address with prefix length [address/prefix length]", + "format": "ipWithRequiredPrefix", + "default": "::/0" + }, + "prefixLengthRange": { + "type": "string", + "description": "Prefix length range. Examples: Specify '1:32' for greater than or equal to 1 and less than or equal to 32. Specify '1:' for greater than or equal to 1. Specify ':32' for less than or equal to 32. Specify '32' for equal to 32. Must be 0 or greater than the length on the prefix property.", + "pattern": "^\\d*:?\\d*$", + "default": "0" + } + }, + "required": ["name", "action"], + "additionalProperties": false + }, + "default": [] + }, + "routeDomain": { + "description": "Specifies the name of the route domain used", + "type": "string", + "default": "0" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RouteMap" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains route map configuration.", + "type": "string", + "const": "RouteMap" + }, + "entries": { + "description": "An array that holds action to take when corresponding entries are matched.", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "Name of the entity", + "type": "integer" + }, + "action": { + "description": "An action to take", + "type": "string", + "enum": [ + "permit", + "deny" + ] + }, + "match": { + "description": "AS path and addresses to match", + "type": "object", + "properties": { + "asPath": { + "description": "RoutingAsPath to match. Defines a BGP AS path access list.", + "type": "string" + }, + "ipv4": { + "description": "IPv4 to match", + "type": "object", + "properties": { + "address": { + "description": "IPv4 addresses to match", + "type": "object", + "properties": { + "prefixList": { + "description": "RoutingPrefixList to match", + "type": "string" + } + }, + "default": {} + }, + "nextHop": { + "description": "IPv4 next hops to match", + "type": "object", + "properties": { + "prefixList": { + "description": "RoutingPrefixList to match", + "type": "string" + } + }, + "default": {} + } + }, + "default": { + "address": {}, + "nextHop": {} + }, + "additionalProperties": false + }, + "ipv6": { + "description": "IPv6 to match", + "type": "object", + "properties": { + "address": { + "description": "IPv6 addresses to match", + "type": "object", + "properties": { + "prefixList": { + "description": "RoutingPrefixList to match", + "type": "string" + } + }, + "default": {} + }, + "nextHop": { + "description": "IPv6 next hops to match", + "type": "object", + "properties": { + "prefixList": { + "description": "RoutingPrefixList to match", + "type": "string" + } + }, + "default": {} + } + }, + "default": { + "address": {}, + "nextHop": {} + }, + "additionalProperties": false + } + }, + "default": { + "ipv4": { + "address": {}, + "nextHop": {} + }, + "ipv6": { + "address": {}, + "nextHop": {} + } + }, + "additionalProperties": false + } + }, + "required": ["name", "action"], + "additionalProperties": false + }, + "default": [] + }, + "routeDomain": { + "description": "Specifies the name of the route domain used by the route map", + "type": "string", + "default": "0" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "RoutingBGP" } } + }, + "then": { + "required": ["class", "localAS"], + "properties": { + "class": { + "description": "Indicates that this property contains Border Gateway Protocol configuration.", + "type": "string", + "const": "RoutingBGP" + }, + "localAS": { + "description": "Local Autonomous System. After the RoutingBGP has been created this value cannot be modified.", + "type": "integer", + "minimum": 1, + "maximum": 4294967295 + }, + "addressFamilies": { + "description": "Address family", + "type": "array", + "items": { + "type": "object", + "required": ["internetProtocol"], + "properties": { + "internetProtocol": { + "description": "Address family. The value 'all' sets both 'ipv4' and 'ipv6' to the 'all' values.", + "type": "string", + "enum": ["ipv4", "ipv6", "all"] + }, + "redistributionList": { + "description": "Redistribution list", + "type": "array", + "items": { + "type": "object", + "required": ["routingProtocol"], + "properties": { + "routingProtocol": { + "description":"Routing protocol", + "type": "string", + "enum": ["connected", "isis", "kernel", "ospf", "rip", "static"] + }, + "routeMap": { + "description": "Route map", + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, + "gracefulRestart": { + "description": "Graceful restart", + "type": "object", + "properties": { + "gracefulResetEnabled": { + "description": "Graceful reset capability", + "type": "boolean", + "default": false + }, + "restartTime": { + "description": "Maximum time needed for neighbor(s) to restart (seconds)", + "type": "integer", + "default": 0, + "minimum": 0, + "maximum": 3600 + }, + "stalePathTime": { + "description": "Maximum time to retain stale paths from restarting neighbor(s) (seconds)", + "type": "integer", + "default": 0, + "minimum": 0, + "maximum": 3600 + } + }, + "default": { + "gracefulResetEnabled": false, + "restartTime": 0, + "stalePathTime": 0 + }, + "additionalProperties": false + }, + "holdTime": { + "description": "Globally set or reset the hold time for all of the neighbors. The holdTime must be either 0 or at least 3 times keepAlive", + "type": "integer", + "default": 90, + "minimum": 0, + "maximum": 65535 + }, + "keepAlive": { + "description": "Globally set or reset the keep alive for all of the neighbors", + "type": "integer", + "default": 30, + "minimum": 0, + "maximum": 65535 + }, + "neighbors": { + "description": "Neighbors", + "type": "array", + "items": { + "type": "object", + "required": ["address", "peerGroup"], + "properties": { + "address": { + "description": "Name", + "type": "string", + "format": "f5ip" + }, + "ebgpMultihop": { + "description": "Allow external BGP members not on directly connected networks", + "type": "integer", + "minimum": 1, + "maximum": 255, + "default": 1 + }, + "peerGroup": { + "description": "Peer group", + "type": "string" + } + }, + "additionalProperties": false + }, + "default": [] + }, + "peerGroups": { + "description": "Peer group", + "type": "array", + "items": { + "description": "Peer groups member", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "description": "Name", + "type": "string" + }, + "addressFamilies": { + "description": "Address family", + "type": "array", + "items": { + "type": "object", + "required": ["internetProtocol"], + "properties": { + "internetProtocol": { + "description": "Address family", + "type": "string", + "enum": ["ipv4", "ipv6"] + }, + "softReconfigurationInboundEnabled": { + "description": "Soft reconfiguration inbound enabled", + "type": "boolean", + "default": false + }, + "routeMap": { + "description": "Route maps", + "type": "object", + "properties": { + "in": { + "description": "Incoming route map", + "type": "string" + }, + "out": { + "description": "Outgoing route map", + "type": "string" + } + }, + "default": {}, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "remoteAS": { + "description": "Remote Autonomous System", + "type": "integer", + "default": 0 + } + }, + "additionalProperties": false + }, + "default": [] + }, + "routeDomain": { + "description": "Specifies the name of the route domain used by the routing bgp", + "type": "string", + "default": "0" + }, + "routerId": { + "description": "Manually override current router identifier (peers will reset)", + "type": "string", + "default": "any6" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "ManagementIpFirewall" } } + }, + "then": { "$ref": "#/definitions/managementIpFirewall" } + } + ], + "definitions": { + "firewallPolicy": { + "description": "Configures firewall policy", + "type": "object", + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains firewall policy configuration", + "type": "string", + "const": "FirewallPolicy" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "rules": { + "description": "Specifies the list of firewall policy rules", + "type": "array", + "items": { "$ref": "#/definitions/firewallRulePolicy" } + } + }, + "additionalProperties": false + }, + "firewallAddressList": { + "title": "Firewall Address List", + "description": "Declares an address-list for use by firewall rules. An address list is a list of IP-address prefixes to compare against the source-IP address and/or destination-IP address in an IP packet", + "type": "object", + "properties": { + "class": { + "title": "Class", + "type": "string", + "const": "FirewallAddressList" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "addresses": { + "type": "array", + "description": "A list of IPv4 and IPv6 addresses and address ranges. You can specify a network with CIDR slash notation.", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "fqdns": { + "type": "array", + "description": "A list of fully qualified domain names.", + "items": { + "type": "string", + "format": "hostname" + }, + "minItems": 1 + }, + "geo": { + "type": "array", + "description": "A list of geographic locations (for example, US:Washington).", + "items": { + "type": "string" + }, + "minItems": 1 + } + }, + "additionalProperties": false, + "required": [ + "class" + ], + "anyOf": [ + { + "required": [ + "addresses" + ] + }, + { + "required": [ + "fqdns" + ] + }, + { + "required": [ + "geo" + ] + } + ] + }, + "firewallPortList": { + "title": "Firewall Port List", + "description": "Declares a port-list for use by firewall rules. A firewall rule can match a packet's source port or destination port against one of the ports in a port list, and can take some action (such as ACCEPT or DROP) for a matching packet.", + "type": "object", + "f5modules": [ + "afm" + ], + "properties": { + "class": { + "title": "Class", + "type": "string", + "const": "FirewallPortList" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "ports": { + "type": "array", + "description": "A list of ports and port ranges (for example, 80, \"8080-8090\").", + "items": { + "type": [ + "integer", + "string" + ] + }, + "minItems": 1 + } + }, + "additionalProperties": false, + "required": [ + "class", + "ports" + ] + }, + "firewallRuleCore": { + "description": "Configures a firewall rule.", + "type": "object", + "required": ["name", "action"], + "properties": { + "name": { + "type": "string", + "description": "Specifies the name of the firewall rule" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "action": { + "description": "Specifies the action that the firewall rule will take on matching packets", + "type": "string", + "enum": [ + "accept", + "drop", + "accept-decisively", + "reject" + ] + }, + "protocol": { + "description": "Specifies the protocol to which the firewall rule applies", + "type": "string", + "enum": [ + "any", + "tcp", + "udp" + ], + "default": "any" + }, + "source": { + "$ref": "#/definitions/firewallRuleSourceCore" + }, + "destination": { + "$ref": "#/definitions/firewallRuleDestinationCore" + }, + "loggingEnabled": { + "description": "Specifies whether the system enables or disables logging for the firewall rule", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "firewallRulePolicy": { + "type": "object", + "allOf": [ + { "$ref": "#/definitions/firewallRuleCore" }, + { + "properties": { + "source": { "$ref": "#/definitions/firewallRuleSourcePolicy" } + } + } + ] + }, + "firewallRuleSourceCore": { + "description": "Configures the packet sources to which the network firewall rule applies", + "type": "object", + "properties": { + "addressLists": { + "type": "array", + "description": "Specifies a list of address lists against which the packet will be compared.", + "items": { + "type": "string" + }, + "additionalProperties": false + }, + "portLists": { + "type": "array", + "description": "Specifies a list of port lists against which the packet will be compared.", + "items": { + "type": "string" + }, + "additionalProperties": false + } + } + }, + "firewallRuleSourcePolicy": { + "type": "object", + "allOf": [ + { "$ref": "#/definitions/firewallRuleSourceCore" }, + { + "type": "object", + "properties": { + "vlans": { + "type": "array", + "description": "Specifies a list of VLANs against which the packets will be compared", + "items": { + "type": "string" + }, + "additionalProperties": false + } + } + } + ] + }, + "firewallRuleDestinationCore": { + "description": "Configures the packet destination to which the network firewall rule applies", + "type": "object", + "properties": { + "addressLists": { + "type": "array", + "description": "Specifies a list of address lists against which the packet will be compared.", + "items": { + "type": "string" + }, + "additionalProperties": false + }, + "portLists": { + "type": "array", + "description": "Specifies a list of port lists against which the packet will be compared.", + "items": { + "type": "string" + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "netAddressList": { + "title": "Network Address List", + "description": "Declares an address-list for use by management IP firewall rules. This property doesn't need an AFM to be provisioned. An address list is a list of IP-address prefixes to compare against the source-IP address and/or destination-IP address in an IP packet", + "type": "object", + "properties": { + "class": { + "title": "Class", + "type": "string", + "const": "NetAddressList" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "addresses": { + "type": "array", + "description": "A list of IPv4 and IPv6 addresses and address ranges. You can specify a network with CIDR slash notation.", + "items": { + "type": "string" + }, + "minItems": 1 + } + }, + "additionalProperties": false, + "required": [ + "class", + "addresses" + ] + }, + "netPortList": { + "title": "Network Port List", + "description": "Declares a port-list for use by management IP firewall rules. This property doesn't need an AFM to be provisioned. A firewall rule can match a packet's source port or destination port against one of the ports in a port list, and can take some action (such as ACCEPT or DROP) for a matching packet.", + "type": "object", + "properties": { + "class": { + "title": "Class", + "type": "string", + "const": "NetPortList" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "ports": { + "type": "array", + "description": "A list of ports and port ranges (for example, 80, \"8080-8090\").", + "items": { + "type": [ + "integer", + "string" + ] + }, + "minItems": 1 + } + }, + "additionalProperties": false, + "required": [ + "class", + "ports" + ] + }, + "managementIpFirewall": { + "description": "Configures the management IP firewall", + "type": "object", + "required": ["class"], + "properties": { + "class": { + "description": "Indicates this property contains management IP firewall configuration.", + "type": "string", + "const": "ManagementIpFirewall" + }, + "label": { + "$ref": "definitions.schema.json#/definitions/Label" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "rules": { + "description": "Specifies the list of firewall rules", + "type": "array", + "items": { "$ref": "#/definitions/firewallRuleCore" } + } + }, + "additionalProperties": false + } + } +} diff --git a/src/schema/1.40.0/openapi.yaml b/src/schema/1.40.0/openapi.yaml new file mode 100644 index 00000000..a88e3afe --- /dev/null +++ b/src/schema/1.40.0/openapi.yaml @@ -0,0 +1,590 @@ +openapi: 3.0.3 +info: + title: F5 BIG-IP Declarative Onboarding + description: This reference describes the BIG-IP DO API and available endpoints. For more details, see https://clouddocs.f5.com/products/extensions/f5-declarative-onboarding/latest/using-do.html. + version: 1.40.0 + contact: + name: BIG-IP Declarative Onboarding + email: solutionsfeedback@f5.com + url: 'https://github.com/F5Networks/f5-declarative-onboarding' + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +servers: + - url: https://192.0.2.1:443/mgmt/shared/declarative-onboarding +paths: + /: + get: + summary: Get status of configuration request + description: Retrieve the status of the most recently deployed configuration request. + operationId: getMostRecentTask + tags: + - Configuration + parameters: + - name: show + in: query + required: false + description: Retrieve original and current configuration. + schema: + type : string + enum: + - full + - name: statusCodes + in: query + required: false + description: | + Determines how BIG-IP DO returns HTTP status codes. + - *legacy*: Returns any errors as the HTTP status. + - *experimental*: Returns a 200 HTTP status code unless there is an actual error with the request. The result in the body of the response contains the status of the task. + schema: + type : string + enum: + - legacy + - experimental + default: legacy + responses: + 200: + description: Configuration was successful. + content: + application/json: + schema: + $ref: '#/components/schemas/task' + examples: + success: + value: + $ref: '#/components/examples/task' + failure: + value: + $ref: '#/components/examples/errorConfig' + 500: + $ref: '#/components/responses/500' + post: + summary: Apply BIG-IP DO configuration + description: Configure the device per the declaration. + operationId: postDeclaration + tags: + - Configuration + requestBody: + description: BIG-IP DO Declaration. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/device' + responses: + 200: + description: Successful synchronous response. + content: + application/json: + schema: + $ref: '#/components/schemas/task' + example: + $ref: '#/components/examples/task' + 202: + description: Successful asynchronous response. + content: + application/json: + schema: + $ref: '#/components/schemas/task' + example: + id: 'c098f4f1-d2a4-4c53-8728-7d1ce5567a4a' + result: + class: Result, + code: 202, + status: RUNNING, + dryRun: false, + message: processing + declaration: + class: Device + schemaVersion: 1.0.0 + async: true + Common: + class: Tenant + myLicense: + class: License + licenseType: regKey + regKey: AAAAA-BBBBB-CCCCC-DDDDD-EEEEEEE + selfLink: 'https://localhost/mgmt/shared/appsvcs/task/c098f4f1-d2a4-4c53-8728-7d1ce5567a4' + 422: + description: Error while applying config. + content: + application/json: + schema: + $ref: '#/components/schemas/task' + example: + $ref: '#/components/examples/errorConfig' + 500: + $ref: '#/components/responses/500' + /config: + get: + summary: Return all original configurations + description: Retrieve the original configuration of all devices. + operationId: getAllConfigs + tags: + - Configuration + responses: + 200: + description: Retrieval was successful. + content: + application/json: + schema: + type: array + items: + allOf: + - $ref: '#/components/schemas/config' + 500: + $ref: '#/components/responses/500' + /config/{machineId}: + get: + summary: Return original configuration by machine ID + description: Retrieve the original configuration of a device by machine ID. + operationId: getConfig + tags: + - Configuration + parameters: + - name: machineId + in: path + required: true + description: The machine ID that is returned by the /shared/identified-devices/config/device-info endpoint. + schema: + type : string + format: uuid + responses: + 200: + description: Retrieval was successful. + content: + application/json: + schema: + $ref: '#/components/schemas/config' + 404: + $ref: '#/components/responses/404' + 500: + $ref: '#/components/responses/500' + delete: + summary: Delete the stored original configuration by config ID + description: Delete the stored original configuration by config ID. This can be used in some cases when BIG-IP DO has gotten into an unusable state. + operationId: deleteConfig + tags: + - Configuration + parameters: + - name: configId + in: path + required: true + description: The config ID that was returned by a GET to /config + schema: + type : string + format: uuid + responses: + 200: + description: Delete was successful. + content: + application/json: + schema: + type: array + example: + [] + 404: + $ref: '#/components/responses/404' + 500: + $ref: '#/components/responses/500' + /info: + get: + summary: /mgmt/shared/appsvcs/info + tags: + - Information + description: | + This returns version and release information for the instance of BIG-IP DO you are using. + It also shows current and minimum required versions of the BIG-IP DO schema. + responses: + 200: + description: Successful response. + content: + application/json: + schema: + type: object + properties: + id: + type: integer + enum: + - 0 + selfLink: + type: string + format: uri + result: + $ref: '#/components/schemas/result' + version: + type: string + description: The version of BIG-IP DO. + release: + type: string + description: The build number of the current version. + schemaCurrent: + type: string + description: The maximum schema version supported. + schemaMinimum: + type: string + description: The minimum schema version supported. + example: + id: 0 + selfLink: https://localhost/mgmt/shared/declarative-onboarding/info, + result: + class: Result, + code: 200, + status: OK, + message: "" + errors: [] + version: 1.30.0 + release: 2 + schemaCurrent: 1.30.0 + schemaMinimum: 1.0.0 + 500: + $ref: '#/components/responses/500' + /inspect: + get: + summary: Return current configuration + description: Retrieve the current configuration of a device. + operationId: getInspect + tags: + - Inspect + parameters: + - name: targetHost + in: query + required: false + description: The IP address or domain name of the host from which to retrieve the current configuration. + schema: + type : string + default: localhost + - name: targetPort + in: query + required: false + description: The port that is used with the targetHost to establish a connection to the device. By default, BIG-IP DO tries to establish a connection to the device using ports 443 and 8443. + schema: + type : integer + minimum: 0 + maximum: 65535 + - name: targetUsername + in: query + required: false + description: The username for the targetHost. + schema: + type : string + default: admin + - name: targetPassword + in: query + required: false + description: The password for the targetHost. + schema: + type : string + default: admin + responses: + 200: + description: Retrieval was successful. + content: + application/json: + schema: + $ref: '#/components/schemas/inspect' + 500: + $ref: '#/components/responses/500' + /task: + get: + summary: Return status of all configurations + description: Retrieve the status of all previously deployed configurations. + operationId: getAllTasks + tags: + - Task + responses: + 200: + description: Retrieval was successful. + content: + application/json: + schema: + type: array + items: + allOf: + - $ref: '#/components/schemas/task' + example: + $ref: '#/components/examples/task' + + 500: + $ref: '#/components/responses/500' + /task/{taskId}: + get: + summary: Return status of configuration by task ID + description: Retrieve the status of a previously deployed configuration by task ID. + operationId: getTask + tags: + - Task + parameters: + - name: taskId + in: path + required: true + description: The task ID. + schema: + type : string + format: uuid + responses: + 200: + description: Retrieval was successful. + content: + application/json: + schema: + $ref: '#/components/schemas/task' + examples: + success: + value: + $ref: '#/components/examples/task' + failure: + value: + $ref: '#/components/examples/errorConfig' + 404: + $ref: '#/components/responses/404' + 500: + $ref: '#/components/responses/500' +components: + schemas: + config: + title: Config + description: The original configuration of a device. + type: object + allOf: + - properties: + id: + type: string + format: uuid + selfLink: + type: string + format: uri + result: + $ref: '#/components/schemas/result' + - $ref: '#/components/schemas/configObject' + configObject: + title: Config Object + type: object + properties: + Common: + type: object + description: A collection of sub-objects that describe the configuration state of a device. + additionalProperties: true + errorConfig: + title: BIG-IP DO Processing Error + description: An error response caused by attempting to apply invalid config. + type: object + properties: + id: + description: Unique ID for task. + type: string + format: uuid + selfLink: + description: URI at which to fetch task on the device. + type: string + format: uri + code: + type: integer + enum: + - 422 + - 500 + status: + type: string + enum: + - ERROR + message: + type: string + errors: + type: array + items: + type: string + result: + $ref: '#/components/schemas/result' + declaration: + $ref: '#/components/schemas/device' + errorProcessing: + title: Bad declaration Error + description: An error response caused by a bad parameter or bad declaration. + type: object + properties: + code: + type: integer + message: + type: string + referer: + type: string + format: ipv4 + restOperationId: + type: integer + kind: + type: string + enum: + - ':resterrorresponse' + device: + $ref: base.schema.json + inspect: + title: Inspect + description: The current configuration of a device. + type: object + properties: + id: + type: string + format: uuid + selfLink: + type: string + format: uri + result: + $ref: '#/components/schemas/result' + declaration: + type: object + properties: + class: + type: string + enum: + - DO + declaration: + $ref: '#/components/schemas/device' + result: + title: Result + description: Standard result object in responses. + type: object + properties: + class: + type: string + enum: + - Result + code: + description: Status code. + type: integer + status: + description: Status string. + type: string + enum: + - OK + - ERROR + - ROLLING_BACK + - RUNNING + - REBOOTING + - REVOKING + message: + description: Overall result message. + type: string + errors: + description: Array of errors that occurred. + type: array + items: + type: string + task: + title: Task + description: The configuration status and associated declaration. + type: object + properties: + id: + description: Unique ID for task. + type: string + format: uuid + selfLink: + description: URI at which to fetch task on the device. + type: string + format: uri + message: + description: Overall result message. + type: string + errors: + description: Array of errors that occurred. + type: array + items: + type: string + result: + $ref: '#/components/schemas/result' + declaration: + $ref: '#/components/schemas/device' + currentConfig: + $ref: '#/components/schemas/configObject' + originalConfig: + $ref: '#/components/schemas/configObject' + examples: + errorConfig: + id: c098f4f1-d2a4-4c53-8728-7d1ce5567a4 + selfLink: 'https://localhost/mgmt/shared/appsvcs/task/c098f4f1-d2a4-4c53-8728-7d1ce5567a4' + code: 422 + status: ERROR + message: 'Error licensing: Invalid reg key' + errors: + - 'Invalid reg key' + result: + class: Result + code: 422 + status: ERROR + dryRun: false + message: 'Error licensing: Invalid reg key' + errors: + - 'Invalid reg key' + declaration: + class: Device + schemaVersion: 1.0.0 + async: true + Common: + class: Tenant + myLicense: + class: License + licenseType: regKey + regKey: AAAAA-BBBBB-CCCCC-DDDDD-EEEEEEE + errorNotFound: + code: 404, + message: 'java.net.ProtocolException: status:404, body:b1994382-8b2d-46c1-9e1b-44bd08925e7b does not exist' + referer: 172.18.6.16 + restOperationId: 46740167 + kind: :resterrorresponse + errorProcessing: + code: 400 + message: 'java.net.ProtocolException: status:400, body:DELETE is only supported for the config endpoint' + referer: '192.168.0.1' + restOperationId: 12345678 + kind: ':resterrorresponse' + task: + id: c098f4f1-d2a4-4c53-8728-7d1ce5567a4 + selfLink: 'https://localhost/mgmt/shared/appsvcs/task/c098f4f1-d2a4-4c53-8728-7d1ce5567a4' + result: + class: Result + code: 200 + status: OK + message: success + declaration: + class: Device + schemaVersion: 1.0.0 + async: true + Common: + class: Tenant + myLicense: + class: License + licenseType: regKey + regKey: AAAAA-BBBBB-CCCCC-DDDDD-EEEEEEE + responses: + 404: + description: ID not found. + content: + application/json: + schema: + title: 404 + description: Not found. + type: object + properties: + code: + type: integer + enum: + - 404 + message: + type: string + referer: + type: string + format: ipv4 + restOperationId: + type: integer + kind: + type: string + example: + $ref: '#/components/examples/errorNotFound' + 500: + description: Something went wrong internally and a bug report should be filed: https://github.com/F5Networks/f5-declarative-onboarding/issues/new/choose. + content: + application/json: + schema: + $ref: '#/components/schemas/errorProcessing' + example: + $ref: '#/components/examples/errorProcessing' diff --git a/src/schema/1.40.0/remote.schema.json b/src/schema/1.40.0/remote.schema.json new file mode 100644 index 00000000..a6f05d61 --- /dev/null +++ b/src/schema/1.40.0/remote.schema.json @@ -0,0 +1,202 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/remote.schema.json", + "title": "F5 BIG-IP Declarative Onboarding request declaration", + "description": "Wrapper for remote onboarding of a BIG-IP device using F5 BIG-IP Declarative Onboarding", + "type": "object", + "required": ["class", "declaration"], + "if": { + "required": ["targetPassphrase"] + }, + "then": { + "dependencies": { + "targetSshKey": { + "not": {} + } + } + }, + "else": { + "if": { + "required": ["targetSshKey"] + }, + "then": { + "dependencies": { + "targetPassphrase": { + "not": {} + } + } + } + }, + "properties": { + "class": { + "description": "Indicates that this is a BIG-IP Declarative Onboarding request", + "type": "string", + "const": "DO" + }, + "$schema": { + "description": "URL of schema against which to validate. Used by validation in your local environment only (via Visual Studio Code, for example)", + "type": "string", + "format": "uri" + }, + "targetHost": { + "description": "Hostname or IP address of ADC to which request applies (default localhost)", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ], + "default": "localhost" + }, + "targetPort": { + "description": "TCP port number of management service on targetHost; default 0 means try common ports", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "targetUsername": { + "description": "Username of principal authorized to modify configuration of targetHost (may not include the character ':'). NOTE: this is generally not required to configure 'localhost' because client authentication and authorization precede invocation of BIG-IP DO. It is also not required for any targetHost if you populate targetTokens", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^[^:]{0,254}$" } + ] + }, + "targetPassphrase": { + "description": "Passphrase for targetUsername account. This is generally not required to configure 'localhost' and is not required when you populate targetTokens", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "targetSshKey": { + "description": "Private key for use in ssh operations. Corresponding public key must be in the targetUsername's ~/.ssh/authorized_keys file on the targetHost. This is only used to do initial account creation in environments where that is necessary. If this value is present, BIG-IP DO will look in the declaration for a user matching targetUsername and set its password via ssh.", + "type": "object", + "required": ["path"], + "properties": { + "path": { + "description": "Full path to private ssh key. File must be owned by restnoded.", + "type": "string" + } + }, + "additionalProperties": false + }, + "targetTokens": { + "description": "One or more HTTP headers (each a property, like 'X-F5-Auth-Token': 'ABCABC') you want to send with queries to the targetHost management service as authentication/authorization tokens", + "oneOf": [ + { + "description": "Pointer to tokens in a format that matches the 'object' schema below", + "type": "string", + "anyOf": [ + { "format": "json-pointer" } + ] + }, + { + "type": "object", + "patternProperties": { + "^[^\\x00-\\x20:\\x7f-\\xff]{1,254}$": { + "type": "string", + "pattern": "^[^\\x00-\\x1f\\x7f-\\xff]{0,8192}$" + } + }, + "additionalProperties": false + } + ] + }, + "targetTimeout": { + "description": "Maximum delay allowed while communicating with targetHost device (seconds, default 900)", + "type": "integer", + "minimum": 1, + "maximum": 900, + "default": 900 + }, + "bigIqSettings": { + "description": "Settings for the management of a BIG-IP which is onboarded via a BIG-IQ.", + "type": "object", + "properties": { + "snapshotWorkingConfig": { + "description": "Whether or not to snapshot the working configuration for current device before the import.", + "type": "boolean", + "default": false + }, + "accessModuleProperties": { + "description": "Key/value properties for importing access module. If apm module is not listed in provision section of current declaration, BIG-IQ will only discover/import ltm module.", + "type": "object", + "propertyNames": { + "description": "The name of the access module property." + }, + "additionalProperties": { + "description": "The value to set for the access module property." + } + }, + "failImportOnConflict": { + "description": "Whether or not to fail import task on conflicts.", + "type": "boolean", + "default": false + }, + "conflictPolicy": { + "description": "Conflict policy for shared objects. For Access, a shared import will Accept/USE_BIGIP for all shared and device-specific objects.", + "type": "string", + "enum": ["NONE", "USE_BIGIP", "USE_BIGIQ", "KEEP_VERSION"] + }, + "deviceConflictPolicy": { + "description": "Conflict policy for device-specific objects. For Access, a device-specific import will Accept/USE_BIGIP for all device-specific objects. If value not provided the value will be the same as conflictPolicy.", + "type": "string", + "enum": ["NONE", "USE_BIGIP", "USE_BIGIQ", "KEEP_VERSION"] + }, + "versionedConflictPolicy": { + "description": "Conflict policy for version-specific objects. This is used for all the devices for which device specific versionedConflictPolicy is not specified. If value not provided the value will be the same as conflictPolicy.", + "type": "string", + "enum": ["NONE", "USE_BIGIP", "USE_BIGIQ", "KEEP_VERSION"] + }, + "clusterName": { + "description": "Cluster display name on BIG-IQ.", + "type": "string" + }, + "useBigiqSync": { + "description": "Instead of using the BIG-IP cluster sync to synchronize cluster devices configuration, use BIG-IQ to push changes to cluster devices during deployment.", + "type": "boolean" + }, + "deployWhenDscChangesPending": { + "description": "Deploy when there are pending DSC changes on BIG-IP.", + "type": "boolean" + }, + "statsConfig": { + "description": "Options for configuring http analytics/avr on BIG-IQ.", + "type": "object", + "required": ["enabled"], + "properties": { + "enabled": { + "description": "Whether or not to enable collecting statistics for this device", + "type": "boolean", + "default": false + }, + "zone": { + "description": "User-defined names that associate BIG-IP devices with one or more data collection device (DCD) systems to provide optimal routing for statistics traffic.", + "type": "string", + "default": "default" + } + } + } + }, + "allOf": [ + { + "if": { + "required": ["failImportOnConflict"], + "properties": { "failImportOnConflict": { "const": false }} + }, + "then": { + "required": ["conflictPolicy"] + } + } + ] + }, + "declaration": { + "description": "Declaration to deploy to targetHost", + "$ref": "base.schema.json#" + } + }, + "additionalProperties": false +} diff --git a/src/schema/1.40.0/security.schema.json b/src/schema/1.40.0/security.schema.json new file mode 100644 index 00000000..0241c4c0 --- /dev/null +++ b/src/schema/1.40.0/security.schema.json @@ -0,0 +1,299 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/security.schema.json", + "title": "F5 BIG-IP Declarative Onboarding security declaration", + "description": "Security properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SecurityAnalytics" } } + }, + "then": { + "$ref": "#/definitions/securityAnalytics" + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SecurityWaf" } } + }, + "then": { + "$ref": "#/definitions/securityWaf" + } + } + ], + "definitions": { + "securityAnalytics": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SecurityAnalytics configuration.", + "type": "string", + "const": "SecurityAnalytics" + }, + "aclRules": { + "description": "Firewall (ACL) security statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": " Specifies whether source/client IP address should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectClientPortEnabled": { + "description": "Specifies whether source/client port should be collected for ACL rule matching.", + "type": "boolean", + "default": false + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectDestinationPortEnabled": { + "description": "Specifies whether the destination port should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectServerSideStatsEnabled": { + "description": "Specifies whether server side statistics (source address translation information, self IP address and pool member address) should be collected for ACL rule matching.", + "type": "boolean", + "default": false + } + } + }, + "collectAllDosStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of all DoS statistics.", + "type": "boolean", + "default": false + }, + "collectedStatsExternalLoggingEnabled": { + "description": "Specifies whether to enable or disable external logging of collected statistics.", + "type": "boolean", + "default": false + }, + "collectedStatsInternalLoggingEnabled": { + "description": "Specifies whether to enable or disable internal logging of collected statistics.", + "type": "boolean", + "default": false + }, + "dns": { + "description": "DNS security statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for DNS security.", + "type": "boolean", + "default": true + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for DNS security.", + "type": "boolean", + "default": true + } + } + }, + "collectDnsStatsEnabled": { + "description": "Specifies whether to enable or disable DNS statistics collection.", + "type": "boolean", + "default": true + }, + "dosL2L4": { + "description": "Network DoS statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for network layer's DoS security.", + "type": "boolean", + "default": true + }, + "collectDestinationGeoEnabled": { + "description": "Specifies whether the destination geo should be collected for network layer's DoS security.", + "type": "boolean", + "default": true + } + } + }, + "collectDosL3StatsEnabled": { + "description": "Specifies whether to enable or disable the collection of DoS L3 statistics.", + "type": "boolean", + "default": true + }, + "collectFirewallAclStatsEnabled": { + "description": "Specifies whther to enable or disable the collection of firewall ACL statistics.", + "type": "boolean", + "default": true + }, + "collectFirewallDropsStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of firewall drops statistics.", + "type": "boolean", + "default": true + }, + "collectIpReputationStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of IP reputation statistics.", + "type": "boolean", + "default": true + }, + "l3L4Errors": { + "description": "Firewall errors statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for firewall errors.", + "type": "boolean", + "default": true + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for firewall errors.", + "type": "boolean", + "default": true + } + } + }, + "publisher": { + "description": "Specifies the external logging publisher used to send statistical data to one or more destinations.", + "type": "string" + }, + "collectSipStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of SIP statistics.", + "type": "boolean", + "default": true + }, + "smtpConfig": { + "description": "Specifies the default SMTP configuration used for exporting CSV or PDF security analytics reports.", + "type": "string" + }, + "collectStaleRulesEnabled": { + "description": "Specifies whether statistics about all firewall rules should be collected in order to present information regarding rule staleness.", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "securityWaf": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SecurityWaf configuration.", + "type": "string", + "const": "SecurityWaf" + }, + "antiVirusProtection": { + "description": "Specifies anti virus protection options.", + "type": "object", + "properties": { + "guaranteeEnforcementEnabled": { + "description": "Specifies whether the system should perform virus checking even if this may slow down the web application.", + "type": "boolean", + "default": true + }, + "hostname": { + "description": "Specifies the server hostname.", + "type": "string", + "format": "hostname" + }, + "port": { + "description": "Specifies the server port.", + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 1344 + } + }, + "required": ["hostname"], + "additionalProperties": false + }, + "advancedSettings": { + "description": "Specifies WAF advanced settings.", + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "name": { + "description": "Specifies the name of the setting.", + "type": "string", + "enum": [ + "ecard_regexp_decimal", + "ecard_regexp_email", + "ecard_regexp_phone", + "icap_uri", + "virus_header_name", + "WhiteHatIP1", + "WhiteHatIP2", + "WhiteHatIP3", + "WhiteHatIP4" + ] + }, + "value": { + "description": "Specifies the desired value for the setting.", + "type": "string", + "minLength": 1 + } + }, + "required": ["name", "value"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "description": "Specifies the name of the setting.", + "type": "string", + "enum": [ + "allow_all_cookies_at_entry_point", + "bypass_upon_asm_down", + "bypass_upon_load", + "cookie_expiration_time_out", + "cookie_httponly_attr", + "cookie_max_age", + "cookie_renewal_time_stamp", + "LogSignatures", + "long_request_buffer_size", + "long_request_mem_percentage", + "MaxFtpSessions", + "MaximumCryptographicOperations", + "MaxSmtpSessions", + "MaxViolationEntries", + "max_filtered_html_length", + "max_json_policy_size", + "max_login_request_body_buffer_size", + "max_raw_request_len", + "max_slow_transactions", + "policy_history_max_total_size", + "policy_history_min_retained_versions", + "ProtocolIndication", + "PRXRateLimit", + "reporting_search_timeout", + "request_buffer_size", + "ResponseBufferSize", + "restart_upon_config_update_error", + "RWLightThreads", + "RWThreads", + "sa_login_expiration_timeout", + "send_content_events", + "single_page_application", + "slow_transaction_timeout", + "total_umu_max_size", + "total_xml_memory" + ] + }, + "value": { + "description": "Specifies the desired value for the setting.", + "type": "integer" + } + }, + "required": ["name", "value"], + "additionalProperties": false + } + ] + } + } + }, + "additionalProperties": false + } + } +} diff --git a/src/schema/1.40.0/system.schema.json b/src/schema/1.40.0/system.schema.json new file mode 100644 index 00000000..85c4b81c --- /dev/null +++ b/src/schema/1.40.0/system.schema.json @@ -0,0 +1,1478 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/F5Networks/f5-declarative-onboarding/main/src/schema/latest/system.schema.json", + "title": "F5 BIG-IP Declarative Onboarding system declaration", + "description": "System properties for onboarding a BIG-IP.", + "allOf": [ + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DeviceCertificate" } } + }, + "then": { + "description": "PKI certificate with optional chain", + "required": ["class", "certificate"], + "allOf": [ + { + "properties": { + "class": { + "description": "Indicates that this property contains device certificate information", + "type": "string", + "const": "DeviceCertificate" + } + } + }, + { "$ref": "definitions.schema.json#/definitions/pkiCertificate" } + ] + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "License" } } + }, + "then": { + "oneOf": [ + { "$ref": "#/definitions/regKeyInfo" }, + { "$ref": "#/definitions/licensePoolInfo" } + ], + "if": { + "required": ["licenseType"], + "properties": { "licenseType": { "const": "licensePool" } } + }, + "then": { + "properties": { + "unitOfMeasure": { + "default": "monthly" + } + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DbVariables" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains global db variable configuration.", + "type": "string", + "const": "DbVariables" + } + }, + "propertyNames": { + "description": "The name of the db variable." + }, + "additionalProperties": { + "description": "The value to set for the db variable." + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Provision" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains module provisioning configuration.", + "type": "string", + "const": "Provision" + } + }, + "propertyNames": { + "description": "The module to provision. Note: 'cgnat' is only supported on TMOS v15+", + "enum": [ + "class", + "afm", + "am", + "apm", + "asm", + "avr", + "cgnat", + "dos", + "fps", + "gtm", + "ilx", + "lc", + "ltm", + "pem", + "swg", + "urldb", + "sslo" + ] + }, + "additionalProperties": { + "description": "The level at which to provision the module.", + "type": "string", + "enum": ["dedicated", "nominal", "minimum", "none"] + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "DNS" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains DNS configuration.", + "type": "string", + "const": "DNS" + }, + "nameServers": { + "description": "IP addresses of name servers to use for DNS.", + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + } + }, + "search": { + "description": "Search domain to use for DNS.", + "type": "array", + "items": { + "type": "string", + "format": "hostname" + } + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "NTP" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains NTP configuration.", + "type": "string", + "const": "NTP" + }, + "servers": { + "description": "IP addresses of servers to use for NTP.", + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ] + } + }, + "timezone": { + "description": "The timezone to set.", + "type": "string", + "default": "UTC" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "HTTPD" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Configures the HTTP daemon for the system. Important: F5 Networks recommends that users of the Configuration utility exit the utility before changes are made to the system using the httpd component. This is because making changes to the system using this component causes a restart of the httpd daemon. Additionally, restarting the httpd daemon creates the necessity for a restart of the Configuration utility.", + "type": "string", + "const": "HTTPD" + }, + "allow": { + "description": "Configures IP addresses for the HTTP clients from which the httpd daemon accepts requests.", + "oneOf": [ + { + "type": "string", + "enum": [ + "all", + "none" + ] + }, + { + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { "format": "ipWithOptionalPrefix" }, + { "const": "all" } + ] + } + } + ], + "default": "all" + }, + "authPamIdleTimeout": { + "description": "Specifies the number of seconds of inactivity that can elapse before the GUI session is automatically logged out.", + "type": "integer", + "minimum": 120, + "maximum": 2147483647, + "default": 1200 + }, + "maxClients": { + "description": "Maximum number of clients allowed to be simultaneously connected.", + "type": "integer", + "minimum": 10, + "maximum": 256, + "default": 10 + }, + "sslCiphersuite": { + "description": "Specifies the ciphers that the system uses.", + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9A-Za-z!:\\-+.~@$%^&*()_=\\[\\]|]+$" + }, + "default": [ + "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-RSA-AES128-SHA", + "ECDHE-RSA-AES256-SHA", + "ECDHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES256-SHA384", + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-AES256-GCM-SHA384", + "ECDHE-ECDSA-AES128-SHA", + "ECDHE-ECDSA-AES256-SHA", + "ECDHE-ECDSA-AES128-SHA256", + "ECDHE-ECDSA-AES256-SHA384", + "AES128-GCM-SHA256", + "AES256-GCM-SHA384", + "AES128-SHA", + "AES256-SHA", + "AES128-SHA256", + "AES256-SHA256" + ] + }, + "sslProtocol": { + "description": "The list of SSL protocols to accept on the management console. A space-separated list of tokens in the format accepted by the Apache mod_ssl SSLProtocol directive.", + "type": "string", + "default": "all -SSLv2 -SSLv3 -TLSv1" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SnmpAgent" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains basic SNMP agent configuration.", + "type": "string", + "const": "SnmpAgent" + }, + "contact": { + "description": "The name of the person who administers the SNMP service for this system.", + "type": "string" + }, + "location": { + "description": "The description of this system's physical location.", + "type": "string" + }, + "allowList": { + "description": "Allowed client IP addresses.", + "type": "array", + "items": { + "type": "string", + "format": "f5ip" + } + }, + "snmpV1": { + "description": "Enables snmpd daemon support of snmpV1 queries.", + "type": "boolean", + "default": true + }, + "snmpV2c": { + "description": "Enables snmpd daemon support of snmpV2c queries.", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SnmpCommunity" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SNMP v1 or v2c community configuration.", + "type": "string", + "const": "SnmpCommunity" + }, + "ipv6": { + "description": "Specifies whether the record applies to IPv6 addresses.", + "type": "boolean", + "default": false + }, + "source": { + "description": "Specifies the source address for access to the MIB.", + "type": "string" + }, + "oid": { + "description": "Specifies the current object identifier (OID) for the record.", + "type": "string" + }, + "access": { + "description": "Whether the user's access level to the MIB is readOnly.", + "type": "string", + "enum": [ "ro", "rw" ], + "default": "ro" + }, + "name": { + "description": "Overrides using the object name as the community name. Use this if you want special characters in the community name.", + "type": "string" + } + }, + "if": { + "required": ["oid"] + }, + "then": { + "required": ["source"] + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SnmpUser" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SNMP v3 user configuration.", + "type": "string", + "const": "SnmpUser" + }, + "authentication": { + "description": "Specifies the user's authentication method and password.", + "type": "object", + "required": [ "protocol", "password" ], + "properties": { + "protocol": { + "description": "Authentication protocol. Values other than 'sha' or 'md5' require BIGIP version 15.1 or above.", + "type": "string", + "enum": ["sha", "sha256", "sha512", "md5"], + "default": "sha" + }, + "password": { + "description": "Specifies the password for the user.", + "type": "string" + } + }, + "additionalProperties": false + }, + "privacy": { + "description": "Specifies the privacy protcol to use to deliver authentication information for this user.", + "type": "object", + "required": [ "protocol", "password" ], + "properties": { + "protocol": { + "description": "Specifies the encryption protocol. Values 'aes192', 'aes192c', 'aes256', and 'aes256c' require BIGIP version 15.1 or above.", + "type": "string", + "enum": ["aes", "aes192", "aes192c", "aes256", "aes256c", "des"], + "default": "aes" + }, + "password": { + "description": "Specifies the password for the user.", + "type": "string" + } + } + }, + "oid": { + "description": "Specifies the current object identifier (OID) for the record.", + "type": "string", + "default": ".1" + }, + "access": { + "description": "Whether the user's access level to the MIB is readOnly.", + "type": "string", + "enum": ["ro", "rw"], + "default": "ro" + }, + "name": { + "description": "Overrides using the object name as the username. Use this if you want special characters in the username.", + "type": "string" + } + }, + "additionalProperties": false, + "if": { + "required": [ "privacy" ] + }, + "then": { + "required": [ "authentication" ] + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SnmpTrapEvents" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SNMP trap configuration.", + "type": "string", + "const": "SnmpTrapEvents" + }, + "agentStartStop": { + "description": "Indicates whether to send a trap when the SNMP agent starts/stops.", + "type": "boolean", + "default": true + }, + "authentication": { + "description": "Indicates whether to send authentication warning traps.", + "type": "boolean", + "default": false + }, + "device": { + "description": "Indicates whether to send device warning traps.", + "type": "boolean", + "default": true + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SnmpTrapDestination" } } + }, + "then": { + "required": ["class", "version", "destination", "port", "network"], + "properties": { + "class": { + "description": "Indicates that this property contains SNMP trap configuration.", + "type": "string", + "const": "SnmpTrapDestination" + }, + "version": { + "description": "Specifies to which Simple Network Management Protocol (SNMP) version the trap destination applies.", + "type": "string", + "enum": ["1", "2c", "3"], + "default": "2c" + }, + "destination": { + "description": "Specifies the address for the trap destination.", + "type": "string", + "oneOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "port": { + "description": "Specifies the port for the trap destination.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 162 + }, + "network": { + "description": "Specifies the trap network. The system sends the SNMP trap out the specified network. 'management' specifies that the system sends the trap out of the management IP address. 'other' specifies that the system sends the trap out of the interface based on the routing tables.", + "type": "string", + "enum": ["management", "other"], + "default": "management" + } + }, + "if": { + "required": ["version"], + "properties": { "version": { "const" : "3" } } }, + "then": { + "required": ["securityName", "authentication"], + "properties": { + "securityName": { + "description": "Specifies the user name the system uses to handle SNMP v3 traps.", + "type": "string" + }, + "authentication": { + "description": "Specifies the user's authentication method and password.", + "type": "object", + "required": [ "protocol", "password" ], + "properties": { + "protocol": { + "description": "Authentication protocol.", + "type": "string", + "enum": ["sha", "md5"] + }, + "password": { + "description": "Specifies the password for the user.", + "type": "string" + } + }, + "additionalProperties": false + }, + "privacy": { + "description": "Specifies the privacy protcol to use to deliver authentication information for this user.", + "type": "object", + "properties": { + "protocol": { + "description": "Specifies the encryption protocol.", + "type": "string", + "enum": ["aes", "des"] + }, + "password": { + "description": "Specifies the password for the user.", + "type": "string" + } + } + }, + "engineId": { + "description": "Specifies the unique identifier (snmpEngineID) of the remote SNMP protocol engine.", + "type": "string" + } + } + }, + "else": { + "required": ["community"], + "properties": { + "community": { + "description": "Specifies the community name for the trap destination.", + "type": "string" + } + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "User" } } + }, + "then": { + "if": { + "properties": { "userType": { "const": "root" } } + }, + "then": { + "required": ["class", "userType", "newPassword", "oldPassword"], + "properties": { + "class": { + "description": "Indicates that this property contains user configuration.", + "type": "string", + "const": "User" + }, + "userType": { + "description": "The type of user.", + "type": "string", + "const": "root" + }, + "newPassword": { + "description": "Password to set for the root user.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "oldPassword": { + "description": "Old password for the root user.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "keys": { + "description": "An array of public keys for the user. If the user is root, this will preserve only the master key and then overwrite the rest in the file: /root/.ssh/authorized_keys.", + "type": "array", + "items": { + "type": "string" + } + }, + "forceInitialPasswordChange": { + "description": "Determines if a password change will be required on the first user login.", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + }, + "else": { + "required": ["class", "userType"], + "properties": { + "class": { + "description": "Indicates that this property contains user configuration.", + "type": "string", + "const": "User" + }, + "userType": { + "description": "The type of user.", + "type": "string", + "const": "regular" + }, + "password": { + "description": "Password for the user.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "partitionAccess": { + "description": "Access control configuration.", + "type": "object", + "properties": { + "Common": { + "$ref": "#/definitions/partitionAccess" + }, + "all-partitions": { + "$ref": "#/definitions/partitionAccess" + } + }, + "additionalProperties": false + }, + "shell": { + "description": "Shell for the user.", + "type": "string", + "enum": ["bash", "tmsh", "none"], + "default": "tmsh" + }, + "keys": { + "description": "An array of public keys for the user. These will overwrite the /home/username/.ssh/authorized_keys if not root.", + "type": "array", + "items": { + "type": "string" + } + }, + "forceInitialPasswordChange": { + "description": "Determines if a password change will be required on the first user login.", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "ManagementIp" } } + }, + "then": { + "required": ["class", "address"], + "properties": { + "class": { + "description": "Indicates this property contains management IP configuration. Note that if you set this you will have to poll for status on the new address.", + "type": "string", + "const": "ManagementIp" + }, + "address": { + "description": "IP address.", + "type": "string", + "format": "ipWithRequiredPrefix" + }, + "remark": { + "description": "To handle rollback to a dynamically configured address, do not set this to 'configured-by-dhcp'", + "$ref": "definitions.schema.json#/definitions/Remark", + "default": "configured-statically by DO" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "ManagementRoute" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates this property contains management route configuration", + "type": "string", + "const": "ManagementRoute" + }, + "remark": { + "$ref": "definitions.schema.json#/definitions/Remark" + }, + "gw": { + "description": "Gateway for the management route.", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "network": { + "description": "IP address/netmask for the management route", + "type": "string", + "anyOf": [ + { "format": "f5ip" }, + { "enum": ["default", "default-inet6"]} + ], + "default": "default" + }, + "mtu": { + "description": "MTU for the management route.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "type": { + "description": "Type of the management route", + "type": "string", + "enum": [ + "interface", + "blackhole" + ] + } + }, + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "network": { + "not": { + "enum": ["default", "default-inet6"] + } + }, + "type": { + "not": { + "enum": ["interface", "blackhole"] + } + } + } + }, + "then": { + "required": ["gw"] + } + }, + { + "if": { + "required": ["type"] + }, + "then": { + "dependencies": { + "gw": { + "not": {} + } + } + } + } + ] + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SyslogRemoteServer" } } + }, + "then": { + "required": ["class", "host"], + "properties": { + "class": { + "description": "Indicates that this property contains Syslog Remote Server Information", + "type": "string", + "const": "SyslogRemoteServer" + }, + "host": { + "description": "Specifies the IP address of a remote server to which syslog sends messages.", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ] + }, + "localIp": { + "description": "Specifies the IP address of the interface syslog binds with in order to log messages to a remote host.", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" } + ] + }, + "remotePort": { + "description": "Specifies the port to which the syslog sends messages.", + "type": "integer", + "minimum": 0, + "maximum": 65535, + "default": 514 + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "System" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates this property contains global system settings", + "type": "string", + "const": "System" + }, + "hostname": { + "description": "Hostname to set for the device. Note: If you set the hostname as part of the Common class, you CANNOT set a hostname in the System class (they are mutually exclusive).", + "type": "string", + "format": "hostname", + "default": "bigip1" + }, + "consoleInactivityTimeout": { + "description": "Configure automatic logout for idle serial console sessions (command line sessions) in seconds. The default value 0 means that no timeout is set.", + "type": "integer", + "minimum": 0, + "maximum": 2147483647, + "default": 0 + }, + "cliInactivityTimeout": { + "description": "Configure automatic logout for idle users in TMSH interactive mode. A setting other than 0 automatically logs a user out after a specified number of seconds, which must be entered in multiples of 60. The default value 0 means that no timeout is set.", + "type": "integer", + "minimum": 0, + "maximum": 128849018820, + "multipleOf": 60, + "default": 0 + }, + "autoPhonehome": { + "description": "Enables the BIG-IP system to send non-confidential, high-level device information to F5 in order to help determine product usage to optimize product development.", + "type": "boolean", + "default": true + }, + "autoCheck": { + "description": "Enables the BIG-IP system to check for and recommend software updates.", + "type": "boolean", + "default": true + }, + "tmshAuditLog": { + "description": "Enables audit logging for tmsh.", + "type": "boolean", + "default": true + }, + "guiAuditLog": { + "description": "Enables audit logging for the GUI. Only available on TMOS v14+", + "type": "boolean", + "default": false + }, + "mcpAuditLog": { + "description": "Enables audit logging for MCP.", + "type": "string", + "enum": [ + "disable", + "enable", + "verbose", + "all" + ], + "default": "enable" + }, + "preserveOrigDhcpRoutes": { + "description": "Determines if DHCP ManagementRoute objects are preserved.", + "type": "boolean", + "default": false + }, + "mgmtDhcpEnabled": { + "description": "Determines if Management DHCP is enabled or not.", + "type": "boolean" + }, + "guiSecurityBanner": { + "description": "Specifies whether the system presents on the login screen the text you specify in guiSecurityBannerText. If you disable this option, the system presents an empty frame in the right portion of the login screen.", + "type": "boolean", + "default": true + }, + "guiSecurityBannerText": { + "description": "Specifies the text to present on the login screen when the guiSecurityBanner is enabled.", + "type": "string", + "default": "Welcome to the BIG-IP Configuration Utility.\n\nLog in with your username and password using the fields on the left." + }, + "usernamePrompt": { + "description": "Specifies the text to present above the user name field on the system's login screen.", + "type": "string", + "default": "Username" + }, + "passwordPrompt": { + "description": "Specifies the text to present above the password field on the system's login screen.", + "type": "string", + "default": "Password" + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "TrafficControl" } } + }, + "then": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates this property contains traffic control configuration", + "type": "string", + "const": "TrafficControl" + }, + "acceptIpOptions": { + "description": "Specifies whether the system accepts IPv4 packets with IP Options.", + "type": "boolean", + "default": false + }, + "acceptIpSourceRoute": { + "description": "Specifies whether the system accepts IPv4 packets with IP source route options that are destined for TMM. To enable this option, you must also enable the acceptIpOptions option.", + "type": "boolean", + "default": false + }, + "allowIpSourceRoute": { + "description": "Specifies whether the system allows IPv4 packets with IP source route options enabled to be routed through TMM. To enable this option, you must also enable the acceptIpOptions option.", + "type": "boolean", + "default": false + }, + "continueMatching": { + "description": "Specifies whether the system matches against a less-specific virtual server when the more-specific one is disabled or rejects / drops the packets depending on the value of rejectUnmatched.", + "type": "boolean", + "default": false + }, + "maxIcmpRate": { + "description": "Specifies the maximum rate per second at which the system issues ICMP errors.", + "type": "integer", + "minimum": 0, + "maximum": 2147483647, + "default": 100 + }, + "maxPortFindLinear": { + "description": "Specifies the maximum of ports to linearly search for outbound connections", + "type": "integer", + "minimum": 0, + "maximum": 61439, + "default": 16 + }, + "maxPortFindRandom": { + "description": "Specifies the maximum of ports to randomly search for outbound connections", + "type": "integer", + "minimum": 0, + "maximum": 1024, + "default": 16 + }, + "maxRejectRate": { + "description": "Specifies the maximum rate per second at which the system issues reject packets (TCP RST or ICMP port unreach).", + "type": "integer", + "minimum": 1, + "maximum": 1000, + "default": 250 + }, + "maxRejectRateTimeout": { + "description": "Specifies the time in seconds which the system ignores ICMP port unreach and TCP RST ratelimits on becoming active after a failover.", + "type": "integer", + "minimum": 0, + "maximum": 300, + "default": 30 + }, + "minPathMtu": { + "description": "Specifies the minimum packet size that can traverse the path without suffering fragmentation", + "type": "integer", + "minimum": 68, + "maximum": 1500, + "default": 296 + }, + "pathMtuDiscovery": { + "description": "Specifies that the system discovers the MTU that it can send over a path without fragmenting TCP packets", + "type": "boolean", + "default": true + }, + "portFindThresholdWarning": { + "description": "Specifies if the ephemeral port-exhaustion threshold warning is to be monitored.", + "type": "boolean", + "default": true + }, + "portFindThresholdTrigger": { + "description": "Specifies the threshold warning's trigger which is the value of random port attempts when attempting to find an unused outbound port for a connection.", + "type": "integer", + "minimum": 1, + "maximum": 12, + "default": 8 + }, + "portFindThresholdTimeout": { + "description": "Specifies the threshold warning's timeout which is the time in seconds since the last trigger value was hit and will drop the tuple if not hit.", + "type": "integer", + "minimum": 0, + "maximum": 300, + "default": 30 + }, + "rejectUnmatched": { + "description": "Specifies, when enabled, that the system returns a TCP RST or ICMP port unreach packet if no virtual servers on the system match the destination address of the incoming packet. When disabled, the system silently drops the unmatched packet.", + "type": "boolean", + "default": true + } + }, + "additionalProperties": false, + "dependencies": { + "acceptIpSourceRoute": { + "if": { + "required": ["acceptIpSourceRoute"], + "properties": { "acceptIpSourceRoute": { "const": true } } + }, + "then": { + "required": ["acceptIpOptions"], + "properties": { "acceptIpOptions": { "const": true } } + } + }, + "allowIpSourceRoute": { + "if": { + "required": ["allowIpSourceRoute"], + "properties": { "allowIpSourceRoute": { "const": true } } + }, + "then": { + "required": ["acceptIpOptions"], + "properties": { "acceptIpOptions": { "const": true } } + } + } + } + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "SSHD" } } + }, + "then": { + "properties": { + "class": { + "description": "Indicates this contains SSH configuration.", + "type": "string", + "const": "SSHD" + }, + "allow": { + "description": "Specifies the list of IP addresses that are allowed to log in to the system. Allow all addresses by using the 'all' value or disallow all addresses using the 'none' value.", + "oneOf": [ + { + "type": "string", + "enum": [ + "all", + "none" + ] + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "banner": { + "description": "Enables or disabled the display of the banner text field when a user logs in.", + "type": "string" + }, + "ciphers": { + "description": "Specifies the ciphers to be included.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "3des-cbc", + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + "aes128-cbc", + "aes192-cbc", + "aes256-cbc", + "aes128-gcm@openssh.com", + "aes256-gcm@openssh.com", + "arcfour", + "arcfour128", + "arcfour256", + "blowfish-cbc", + "cast128-cbc", + "chacha20-poly1305@openssh.com" + ] + } + }, + "inactivityTimeout": { + "description": "Specifies the number of seconds before inactivity causes an SSH session to log out.", + "type": "integer", + "default": 0, + "minimum": 0, + "maximum": 2147483647 + }, + "loginGraceTime": { + "description": "Specifies the login grace period that will be included. This is in the number of seconds.", + "type": "integer" + }, + "MACS": { + "description": "Specifies the MACs that will be included.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "hmac-sha1", + "hmac-ripemd160", + "hmac-md5", + "hmac-md5-96", + "hmac-sha1-96", + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-md5-etm@openssh.com", + "hmac-md5-96-etm@openssh.com", + "hmac-ripemd160-etm@openssh.com", + "hmac-sha1-etm@openssh.com", + "hmac-sha1-96-etm@openssh.com", + "hmac-sha2-256-etm@openssh.com", + "hmac-sha2-512-etm@openssh.com", + "umac-64@openssh.com", + "umac-128@openssh.com", + "umac-64-etm@openssh.com", + "umac-128-etm@openssh.com" + ] + } + }, + "kexAlgorithms": { + "description": "Specifies the KexAlgorithms that will be included.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "diffie-hellman-group1-sha1", + "diffie-hellman-group14-sha1", + "diffie-hellman-group14-sha256", + "diffie-hellman-group16-sha512", + "diffie-hellman-group18-sha512", + "diffie-hellman-group-exchange-sha1", + "diffie-hellman-group-exchange-sha256", + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "curve25519-sha256", + "curve25519-sha256@libssh.org", + "gss-gex-sha1-", + "gss-group1-sha1-", + "gss-group14-sha1-" + ] + } + }, + "maxAuthTries": { + "description": "Specifies the max auth tries to be included.", + "type": "integer" + }, + "maxStartups": { + "description": "Specifies the max startups to include.", + "type": "string" + }, + "protocol": { + "description": "Specifies the protocol to be included.", + "type": "integer", + "minimum": 1, + "maximum": 2 + } + }, + "additionalProperties": false + } + }, + { + "if": { + "required": ["class"], + "properties": { "class": { "const": "Disk" } } + }, + "then": { + "properties": { + "class": { + "description": "Indicates this contains Disk configuration. This API is experimental and subject to change.", + "type": "string", + "const": "Disk" + }, + "applicationData": { + "description": "Specifies the size in kilobytes for the application data. This size should be less than the current size. This API is experimental and subject to change.", + "type": "integer", + "minimum": 0, + "multipleOf": 4096 + } + }, + "additionalProperties": false + } + } + ], + "definitions": { + "partitionAccess": { + "description": "The partition - either 'Common' or 'all-partitions'.", + "type": "object", + "required": ["role"], + "properties": { + "role": { + "description": "Role for the user.", + "type": "string", + "enum": [ + "admin", + "auditor", + "guest", + "manager", + "operator", + "user-manager", + "application-editor", + "certificate-manager", + "irule-manager", + "no-access", + "resource-admin" + ] + } + }, + "additionalProperties": false + }, + "regKeyInfo": { + "description": "Registration key information.", + "required": ["class", "licenseType"], + "if": { + "properties": { "revokeCurrent": { "const": false }} + }, + "then": { + "required": ["regKey"] + }, + "properties": { + "class": { + "description": "Indicates that this property contains licensing information.", + "type": "string", + "const": "License" + }, + "licenseType": { + "description": "The type of license", + "type": "string", + "const": "regKey" + }, + "regKey": { + "description": "Registration key.", + "type": "string", + "pattern": "^([A-Z]{5}-[A-Z]{5}-[A-Z]{5}-[A-Z]{5}-[A-Z]{7})|([A-Z][0-9]{4}-[0-9]{5}-[0-9]{5}-[0-9]{5}-[0-9]{7})$" + }, + "addOnKeys": { + "description": "Add on keys.", + "type": "array", + "items": { + "type": "string", + "pattern": "^[A-Z]{7}-[A-Z]{7}$", + "uniqueItems": true + } + }, + "overwrite": { + "description": "Whether or not to overwrite the current license if the device is already licensed.", + "type": "boolean", + "default": false + }, + "revokeCurrent": { + "description": "Whether or not to revoke the current license if the device is already licensed.", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "licensePoolInfo": { + "required": ["class", "licenseType"], + "if": { + "required": ["reachable"], + "properties": { "reachable": { "const": false }} + }, + "then": { + "if": { + "required": ["licensePool"] + }, + "then": { + "required": ["hypervisor"] + } + }, + "else": { + "not": { "required": ["tenant"] }, + "if": { + "required": ["licensePool"] + }, + "then": { + "required": ["bigIpUsername", "bigIpPassword"] + } + }, + "properties": { + "class": { + "description": "Indicates that this property contains licensing information.", + "type": "string", + "const": "License" + }, + "licenseType": { + "description": "The type of license", + "type": "string", + "const": "licensePool" + }, + "licensePool": { + "description": "Name of the BIG-IQ license pool from which to get a new license.", + "type": "string" + }, + "skuKeyword1": { + "description": "skuKeyword1 parameter for subscription licensing.", + "type": "string" + }, + "skuKeyword2": { + "description": "skuKeyword2 parameter for subscription licensing.", + "type": "string" + }, + "unitOfMeasure": { + "description": "unitOfMeasure parameter for subscription licensing.", + "type": "string", + "enum": ["yearly", "monthly", "daily", "hourly"] + }, + "hypervisor": { + "description": "Hypervisor which is running the BIG-IP. Required by BIG-IQ if 'reachable' is false.", + "type": "string", + "oneOf": [ + { "enum": ["aws", "azure", "gce", "vmware", "hyperv", "kvm", "xen", "alibaba"] }, + { "pattern": "0x[0-9a-zA-Z]*" } + ] + }, + "bigIpUsername": { + "description": "An admin user on the BIG-IP. Used by BIG-IQ to login to BIG-IP if 'reachable' is true.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "bigIpPassword": { + "description": "Password for the user in bigIpUsername. Used by BIG-IQ to login to BIG-IP if 'reachable' is true.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "chargebackTag": { + "description": "An optional text string which can be used as a charge back tag.", + "type": "string" + }, + "overwrite": { + "description": "Whether or not to overwrite the license if the device is already licensed.", + "type": "boolean", + "default": false + }, + "revokeFrom": { + "description": "Current license should be revoked from the pool specified. Either just the name of the pool (if old license is on the same BIG-IQ as in the main License section) or full licensePoolInfo (if old license is on a different BIG-IQ)", + "oneOf": [ + { "type": "string" }, + { + "required": ["licensePool"], + "properties": { + "licensePool": { + "description": "Name of the BIG-IQ license pool.", + "type": "string" + } + }, + "allOf": [ + { "$ref": "#/definitions/bigIqHostInfo" } + ] + } + ] + }, + "tenant": { + "description": "An optional description for the license. Can be useful in a clustered environment. Requires that reachable is set to false.", + "type": "string" + } + }, + "allOf": [ + { "$ref": "#/definitions/bigIqHostInfo" } + ] + }, + "bigIqHostInfo": { + "description": "BIG-IQ host/credentials information", + "type": "object", + "allOf": [ + { + "if": { + "required": ["bigIqPassword"] + }, + "then": { + "dependencies": { + "bigIqPasswordUri": { + "not": {} + } + } + } + }, + { + "if": { + "required": ["bigIqHost"] + }, + "then": { + "if": { "not": {"properties": { "bigIqHost": { "const": "localhost" } } } }, + "then": { + "required": ["bigIqUsername"], + "oneOf": [ + { "required": ["bigIqPassword"] }, + { "required": ["bigIqPasswordUri"] } + ] + } + } + } + ], + "properties": { + "bigIqHost": { + "description": "The BIG-IQ hostname or IP address.", + "type": "string", + "anyOf": [ + { "format": "ipv4" }, + { "format": "ipv6" }, + { "format": "hostname" } + ] + }, + "bigIqUsername": { + "description": "An admin user on the BIG-IQ.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^[^:]{0,254}$" } + ] + }, + "bigIqPassword": { + "description": "Password for the user in bigIqUsername.", + "type": "string", + "anyOf": [ + { "format": "json-pointer" }, + { "pattern": "^.{0,254}$" } + ] + }, + "bigIqPasswordUri": { + "description": "URI which will return the password for the user in bigIqUsername.", + "type": "string", + "format": "uri" + }, + "bigIqAuthProvider": { + "description": "Name of auth provider on BIG-IQ. Default is to use TMOS.", + "type": "string" + }, + "reachable": { + "description": "Whether or not BIG-IQ has a route to the BIG-IP device.", + "type": "boolean", + "default": true + } + } + } + } +} diff --git a/src/schema/latest/base.schema.json b/src/schema/latest/base.schema.json index f8b76dd6..65a855b6 100644 --- a/src/schema/latest/base.schema.json +++ b/src/schema/latest/base.schema.json @@ -10,6 +10,7 @@ "description": "Version of BIG-IP Declarative Onboarding schema this declaration uses.", "type": "string", "enum": [ + "1.40.0", "1.39.0", "1.38.0", "1.37.0", @@ -211,7 +212,8 @@ "FirewallPolicy", "FirewallAddressList", "FirewallPortList", - "SecurityAnalytics" + "SecurityAnalytics", + "SecurityWaf" ] } }, diff --git a/src/schema/latest/network.schema.json b/src/schema/latest/network.schema.json index ca51083e..686b069a 100644 --- a/src/schema/latest/network.schema.json +++ b/src/schema/latest/network.schema.json @@ -824,6 +824,11 @@ "additionalProperties": false }, "default": [] + }, + "routeDomain": { + "description": "Specifies the name of the route domain used", + "type": "string", + "default": "0" } }, "additionalProperties": false diff --git a/src/schema/latest/openapi.yaml b/src/schema/latest/openapi.yaml index 259bdeb4..a88e3afe 100644 --- a/src/schema/latest/openapi.yaml +++ b/src/schema/latest/openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.0.3 info: title: F5 BIG-IP Declarative Onboarding description: This reference describes the BIG-IP DO API and available endpoints. For more details, see https://clouddocs.f5.com/products/extensions/f5-declarative-onboarding/latest/using-do.html. - version: 1.39.0 + version: 1.40.0 contact: name: BIG-IP Declarative Onboarding email: solutionsfeedback@f5.com diff --git a/src/schema/latest/security.schema.json b/src/schema/latest/security.schema.json index afe3549c..0241c4c0 100644 --- a/src/schema/latest/security.schema.json +++ b/src/schema/latest/security.schema.json @@ -10,153 +10,290 @@ "properties": { "class": { "const": "SecurityAnalytics" } } }, "then": { + "$ref": "#/definitions/securityAnalytics" + } + }, + { + "if": { "required": ["class"], - "properties": { - "class": { - "description": "Indicates that this property contains SecurityAnalytics configuration.", - "type": "string", - "const": "SecurityAnalytics" - }, - "aclRules": { - "description": "Firewall (ACL) security statistics collection options.", - "type": "object", - "properties": { - "collectClientIpEnabled": { - "description": " Specifies whether source/client IP address should be collected for ACL rule matching.", - "type": "boolean", - "default": true - }, - "collectClientPortEnabled": { - "description": "Specifies whether source/client port should be collected for ACL rule matching.", - "type": "boolean", - "default": false - }, - "collectDestinationIpEnabled": { - "description": "Specifies whether the destination IP address should be collected for ACL rule matching.", - "type": "boolean", - "default": true - }, - "collectDestinationPortEnabled": { - "description": "Specifies whether the destination port should be collected for ACL rule matching.", - "type": "boolean", - "default": true - }, - "collectServerSideStatsEnabled": { - "description": "Specifies whether server side statistics (source address translation information, self IP address and pool member address) should be collected for ACL rule matching.", - "type": "boolean", - "default": false - } + "properties": { "class": { "const": "SecurityWaf" } } + }, + "then": { + "$ref": "#/definitions/securityWaf" + } + } + ], + "definitions": { + "securityAnalytics": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SecurityAnalytics configuration.", + "type": "string", + "const": "SecurityAnalytics" + }, + "aclRules": { + "description": "Firewall (ACL) security statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": " Specifies whether source/client IP address should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectClientPortEnabled": { + "description": "Specifies whether source/client port should be collected for ACL rule matching.", + "type": "boolean", + "default": false + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectDestinationPortEnabled": { + "description": "Specifies whether the destination port should be collected for ACL rule matching.", + "type": "boolean", + "default": true + }, + "collectServerSideStatsEnabled": { + "description": "Specifies whether server side statistics (source address translation information, self IP address and pool member address) should be collected for ACL rule matching.", + "type": "boolean", + "default": false } - }, - "collectAllDosStatsEnabled": { - "description": "Specifies whether to enable or disable the collection of all DoS statistics.", - "type": "boolean", - "default": false - }, - "collectedStatsExternalLoggingEnabled": { - "description": "Specifies whether to enable or disable external logging of collected statistics.", - "type": "boolean", - "default": false - }, - "collectedStatsInternalLoggingEnabled": { - "description": "Specifies whether to enable or disable internal logging of collected statistics.", - "type": "boolean", - "default": false - }, - "dns": { - "description": "DNS security statistics collection options.", - "type": "object", - "properties": { - "collectClientIpEnabled": { - "description": "Specifies whether source/client IP address should be collected for DNS security.", - "type": "boolean", - "default": true - }, - "collectDestinationIpEnabled": { - "description": "Specifies whether the destination IP address should be collected for DNS security.", - "type": "boolean", - "default": true - } + } + }, + "collectAllDosStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of all DoS statistics.", + "type": "boolean", + "default": false + }, + "collectedStatsExternalLoggingEnabled": { + "description": "Specifies whether to enable or disable external logging of collected statistics.", + "type": "boolean", + "default": false + }, + "collectedStatsInternalLoggingEnabled": { + "description": "Specifies whether to enable or disable internal logging of collected statistics.", + "type": "boolean", + "default": false + }, + "dns": { + "description": "DNS security statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for DNS security.", + "type": "boolean", + "default": true + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for DNS security.", + "type": "boolean", + "default": true } - }, - "collectDnsStatsEnabled": { - "description": "Specifies whether to enable or disable DNS statistics collection.", - "type": "boolean", - "default": true - }, - "dosL2L4": { - "description": "Network DoS statistics collection options.", - "type": "object", - "properties": { - "collectClientIpEnabled": { - "description": "Specifies whether source/client IP address should be collected for network layer's DoS security.", - "type": "boolean", - "default": true - }, - "collectDestinationGeoEnabled": { - "description": "Specifies whether the destination geo should be collected for network layer's DoS security.", - "type": "boolean", - "default": true - } + } + }, + "collectDnsStatsEnabled": { + "description": "Specifies whether to enable or disable DNS statistics collection.", + "type": "boolean", + "default": true + }, + "dosL2L4": { + "description": "Network DoS statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for network layer's DoS security.", + "type": "boolean", + "default": true + }, + "collectDestinationGeoEnabled": { + "description": "Specifies whether the destination geo should be collected for network layer's DoS security.", + "type": "boolean", + "default": true + } + } + }, + "collectDosL3StatsEnabled": { + "description": "Specifies whether to enable or disable the collection of DoS L3 statistics.", + "type": "boolean", + "default": true + }, + "collectFirewallAclStatsEnabled": { + "description": "Specifies whther to enable or disable the collection of firewall ACL statistics.", + "type": "boolean", + "default": true + }, + "collectFirewallDropsStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of firewall drops statistics.", + "type": "boolean", + "default": true + }, + "collectIpReputationStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of IP reputation statistics.", + "type": "boolean", + "default": true + }, + "l3L4Errors": { + "description": "Firewall errors statistics collection options.", + "type": "object", + "properties": { + "collectClientIpEnabled": { + "description": "Specifies whether source/client IP address should be collected for firewall errors.", + "type": "boolean", + "default": true + }, + "collectDestinationIpEnabled": { + "description": "Specifies whether the destination IP address should be collected for firewall errors.", + "type": "boolean", + "default": true + } + } + }, + "publisher": { + "description": "Specifies the external logging publisher used to send statistical data to one or more destinations.", + "type": "string" + }, + "collectSipStatsEnabled": { + "description": "Specifies whether to enable or disable the collection of SIP statistics.", + "type": "boolean", + "default": true + }, + "smtpConfig": { + "description": "Specifies the default SMTP configuration used for exporting CSV or PDF security analytics reports.", + "type": "string" + }, + "collectStaleRulesEnabled": { + "description": "Specifies whether statistics about all firewall rules should be collected in order to present information regarding rule staleness.", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "securityWaf": { + "required": ["class"], + "properties": { + "class": { + "description": "Indicates that this property contains SecurityWaf configuration.", + "type": "string", + "const": "SecurityWaf" + }, + "antiVirusProtection": { + "description": "Specifies anti virus protection options.", + "type": "object", + "properties": { + "guaranteeEnforcementEnabled": { + "description": "Specifies whether the system should perform virus checking even if this may slow down the web application.", + "type": "boolean", + "default": true + }, + "hostname": { + "description": "Specifies the server hostname.", + "type": "string", + "format": "hostname" + }, + "port": { + "description": "Specifies the server port.", + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 1344 } }, - "collectDosL3StatsEnabled": { - "description": "Specifies whether to enable or disable the collection of DoS L3 statistics.", - "type": "boolean", - "default": true - }, - "collectFirewallAclStatsEnabled": { - "description": "Specifies whther to enable or disable the collection of firewall ACL statistics.", - "type": "boolean", - "default": true - }, - "collectFirewallDropsStatsEnabled": { - "description": "Specifies whether to enable or disable the collection of firewall drops statistics.", - "type": "boolean", - "default": true - }, - "collectIpReputationStatsEnabled": { - "description": "Specifies whether to enable or disable the collection of IP reputation statistics.", - "type": "boolean", - "default": true - }, - "l3L4Errors": { - "description": "Firewall errors statistics collection options.", - "type": "object", - "properties": { - "collectClientIpEnabled": { - "description": "Specifies whether source/client IP address should be collected for firewall errors.", - "type": "boolean", - "default": true + "required": ["hostname"], + "additionalProperties": false + }, + "advancedSettings": { + "description": "Specifies WAF advanced settings.", + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "name": { + "description": "Specifies the name of the setting.", + "type": "string", + "enum": [ + "ecard_regexp_decimal", + "ecard_regexp_email", + "ecard_regexp_phone", + "icap_uri", + "virus_header_name", + "WhiteHatIP1", + "WhiteHatIP2", + "WhiteHatIP3", + "WhiteHatIP4" + ] + }, + "value": { + "description": "Specifies the desired value for the setting.", + "type": "string", + "minLength": 1 + } + }, + "required": ["name", "value"], + "additionalProperties": false }, - "collectDestinationIpEnabled": { - "description": "Specifies whether the destination IP address should be collected for firewall errors.", - "type": "boolean", - "default": true + { + "type": "object", + "properties": { + "name": { + "description": "Specifies the name of the setting.", + "type": "string", + "enum": [ + "allow_all_cookies_at_entry_point", + "bypass_upon_asm_down", + "bypass_upon_load", + "cookie_expiration_time_out", + "cookie_httponly_attr", + "cookie_max_age", + "cookie_renewal_time_stamp", + "LogSignatures", + "long_request_buffer_size", + "long_request_mem_percentage", + "MaxFtpSessions", + "MaximumCryptographicOperations", + "MaxSmtpSessions", + "MaxViolationEntries", + "max_filtered_html_length", + "max_json_policy_size", + "max_login_request_body_buffer_size", + "max_raw_request_len", + "max_slow_transactions", + "policy_history_max_total_size", + "policy_history_min_retained_versions", + "ProtocolIndication", + "PRXRateLimit", + "reporting_search_timeout", + "request_buffer_size", + "ResponseBufferSize", + "restart_upon_config_update_error", + "RWLightThreads", + "RWThreads", + "sa_login_expiration_timeout", + "send_content_events", + "single_page_application", + "slow_transaction_timeout", + "total_umu_max_size", + "total_xml_memory" + ] + }, + "value": { + "description": "Specifies the desired value for the setting.", + "type": "integer" + } + }, + "required": ["name", "value"], + "additionalProperties": false } - } - }, - "publisher": { - "description": "Specifies the external logging publisher used to send statistical data to one or more destinations.", - "type": "string" - }, - "collectSipStatsEnabled": { - "description": "Specifies whether to enable or disable the collection of SIP statistics.", - "type": "boolean", - "default": true - }, - "smtpConfig": { - "description": "Specifies the default SMTP configuration used for exporting CSV or PDF security analytics reports.", - "type": "string" - }, - "collectStaleRulesEnabled": { - "description": "Specifies whether statistics about all firewall rules should be collected in order to present information regarding rule staleness.", - "type": "boolean", - "default": false + ] } - }, - "additionalProperties": false - } + } + }, + "additionalProperties": false } - ] + } } diff --git a/src/schema/latest/system.schema.json b/src/schema/latest/system.schema.json index 6b0852ed..85c4b81c 100644 --- a/src/schema/latest/system.schema.json +++ b/src/schema/latest/system.schema.json @@ -910,6 +910,16 @@ "description": "Specifies the text to present on the login screen when the guiSecurityBanner is enabled.", "type": "string", "default": "Welcome to the BIG-IP Configuration Utility.\n\nLog in with your username and password using the fields on the left." + }, + "usernamePrompt": { + "description": "Specifies the text to present above the user name field on the system's login screen.", + "type": "string", + "default": "Username" + }, + "passwordPrompt": { + "description": "Specifies the text to present above the password field on the system's login screen.", + "type": "string", + "default": "Password" } }, "additionalProperties": false diff --git a/test/integration/bodies/network.json b/test/integration/bodies/network.json index 979eeee0..588ba47c 100644 --- a/test/integration/bodies/network.json +++ b/test/integration/bodies/network.json @@ -183,7 +183,8 @@ "prefix": "1111:2222::/127", "prefixLengthRange": "128" } - ] + ], + "routeDomain": "0" }, "testRoutingPrefixList2": { "class": "RoutingPrefixList", @@ -194,7 +195,8 @@ "prefix": "10.3.3.0/24", "prefixLengthRange": "30:32" } - ] + ], + "routeDomain": "0" }, "testRouteMap": { "class": "RouteMap", diff --git a/test/integration/common.js b/test/integration/common.js index 404d9386..f3ced08f 100644 --- a/test/integration/common.js +++ b/test/integration/common.js @@ -18,7 +18,8 @@ const fs = require('fs'); const qs = require('querystring'); -const request = require('request'); +const parseUrl = require('url').parse; +const requestUtil = require('@f5devcentral/atg-shared-utilities').requestUtils; const util = require('util'); const constants = require('./constants'); const logger = require('./logger').getInstance(); @@ -37,15 +38,6 @@ module.exports = { return util.promisify(fs.appendFile)(filename, data); }, - /** - * requestPromise - async/await wrapper for request - * @options {Object} - options for request - * Returns a Promise with response/error - */ - requestPromise(options) { - return util.promisify(request)(options); - }, - /** * delayPromise- promise based timeout function * @time {Integer} - Time in milliseconds to wait @@ -110,11 +102,11 @@ module.exports = { const options = module.exports.buildBody(url, body, auth, method); module.exports.sendRequest(options) .then((response) => { - logger.debug(`current status: ${response.response.statusCode}, waiting for ${expectedCode}`); - if (response.response.statusCode === expectedCode) { + logger.debug(`current status: ${response.statusCode}, waiting for ${expectedCode}`); + if (response.statusCode === expectedCode) { resolve(response.body); } else { - reject(new Error(response.response.statusCode)); + reject(new Error(response.statusCode)); } }) .catch((error) => { @@ -144,14 +136,8 @@ module.exports = { constants.PORT)}${constants.DO_API}?${query}`, null, auth, 'GET'); module.exports.sendRequest(options) .then((response) => { - const statusCode = response.response.statusCode; - - let parsedResponse; - try { - parsedResponse = JSON.parse(response.body); - } catch (err) { - parsedResponse = response.body; - } + const statusCode = response.statusCode; + const parsedResponse = response.body; logger.debug(`current status: ${statusCode}, waiting for ${expectedCode}`); if ([constants.HTTP_SUCCESS, constants.HTTP_ACCEPTED].indexOf(statusCode) < 0) { @@ -188,7 +174,7 @@ module.exports = { return this.testRequest(null, `${doUrl}/config`, auth, constants.HTTP_SUCCESS, 'GET', null, retryErrors) .then((body) => { - const promises = JSON.parse(body).map((config) => { + const promises = body.map((config) => { logger.debug(`Deleting original config ${config.id}`); return this.sendRequest( this.buildBody(`${doUrl}/config/${config.id}`, null, auth, 'DELETE'), @@ -247,7 +233,6 @@ module.exports = { constants.PORT)}${constants.DO_API}?show=full`, null, auth, 'GET'); module.exports.sendRequest(options) .then((response) => response.body) - .then(JSON.parse) .then((parsedResponse) => { resolve(parsedResponse); }) @@ -275,13 +260,14 @@ module.exports = { */ sendRequest(options, retryOptions) { const func = function () { - return new Promise((resolve, reject) => { - request(options, (error, response, body) => { - if (error) { reject(error); } - const responseObj = { response, body }; - resolve(responseObj); - }); - }); + return requestUtil.send( + options, + options.body, + { + returnResponseObj: true, + rejectErrStatusCodes: false + } + ); }; if (retryOptions) { @@ -316,13 +302,16 @@ module.exports = { * (either username/password or a token) */ buildBody(url, data, auth, method) { - const options = { - method, - url, - headers: { - 'Content-Type': 'application/json' + const options = Object.assign( + {}, + parseUrl(url), + { + method, + headers: { + 'Content-Type': 'application/json' + } } - }; + ); if (auth && 'token' in auth) { options.headers['X-F5-Auth-Token'] = auth.token; @@ -330,7 +319,7 @@ module.exports = { options.headers.Authorization = module.exports.buildAuthenticationString(auth); } if (data) { - options.body = JSON.stringify(data); + options.body = data; } return options; } diff --git a/test/integration/property/propertiesCommon.js b/test/integration/property/propertiesCommon.js index 0b48db66..70669dbb 100644 --- a/test/integration/property/propertiesCommon.js +++ b/test/integration/property/propertiesCommon.js @@ -65,16 +65,7 @@ function getAuth() { } function sendRequest(options, retryOptions) { - return common.sendRequest(options, retryOptions || { trials: 3, timeInterval: 500 }) - .then((response) => { - let body; - try { - body = JSON.parse(response.body); - } catch (err) { - body = response.body; - } - return Object.assign(response.response, { body }); - }); + return common.sendRequest(options, retryOptions || { trials: 3, timeInterval: 500 }); } function getTestInfo(currentTest) { diff --git a/test/integration/property/propertiesSecurityWaf.js b/test/integration/property/propertiesSecurityWaf.js new file mode 100644 index 00000000..9b4bc8b8 --- /dev/null +++ b/test/integration/property/propertiesSecurityWaf.js @@ -0,0 +1,169 @@ +/** + * Copyright 2023 F5 Networks, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const { + assertClass, + deProvisionModules, + provisionModules +} = require('./propertiesCommon'); + +describe('Security Waf', function testSecurityWafSuite() { + this.timeout(900000); + + before(() => { + const modules = ['asm']; + return provisionModules(modules); + }); + + after(() => { + const modules = ['asm']; + return deProvisionModules(modules); + }); + + it('Anti Virus Protection', () => { + const options = { + skipIdempotentCheck: true, + getMcpObject: { + className: 'AntiVirusProtection' + } + }; + + const properties = [ + { + name: 'antiVirusProtection', + inputValue: [ + undefined, + { + guaranteeEnforcementEnabled: false, + hostname: 'do.test', + port: 123 + }, + undefined + ], + expectedValue: [ + { + guaranteeEnforcement: true, + hostname: '', + port: 1344 + }, + { + guaranteeEnforcement: false, + hostname: 'do.test', + port: 123 + }, + { + guaranteeEnforcement: true, + hostname: '', + port: 1344 + } + ], + extractFunction: (o) => o + } + ]; + + return assertClass('SecurityWaf', properties, options); + }); + + it('Advanced Settings', () => { + const options = { + skipIdempotentCheck: true, + getMcpObject: { + className: 'WafAdvancedSettings', + itemKind: 'tm:asm:advanced-settings:advanced-settingstate', + skipNameCheck: true + }, + findAll: true + }; + + const properties = [ + { + name: 'advancedSettings', + inputValue: [ + undefined, + [ + { + name: 'max_raw_request_len', + value: 25000 + }, + { + name: 'reporting_search_timeout', + value: 100 + }, + { + name: 'virus_header_name', + value: 'X-Virus-Name,X-Infection-Found,X-Virus-ID' + } + ], + undefined + ], + expectedValue: [ + [ + { + name: 'max_raw_request_len', + value: 5000 + }, + { + name: 'reporting_search_timeout', + value: 60 + }, + { + value: 'X-Virus-Name,X-Infection-Found', + name: 'virus_header_name' + } + ], + [ + { + name: 'max_raw_request_len', + value: 25000 + }, + { + name: 'reporting_search_timeout', + value: 100 + }, + { + value: 'X-Virus-Name,X-Infection-Found,X-Virus-ID', + name: 'virus_header_name' + } + ], + [ + { + name: 'max_raw_request_len', + value: 5000 + }, + { + name: 'reporting_search_timeout', + value: 60 + }, + { + value: 'X-Virus-Name,X-Infection-Found', + name: 'virus_header_name' + } + ] + ], + extractFunction: (o) => { + const updatedSettings = ['max_raw_request_len', 'reporting_search_timeout', 'virus_header_name']; + const settings = o.filter((setting) => updatedSettings.indexOf(setting.name) >= 0) + .map((setting) => ({ name: setting.name, value: setting.value })); + return settings; + } + } + ]; + + return assertClass('SecurityWaf', properties, options); + }); +}); diff --git a/test/integration/property/propertiesSystem.js b/test/integration/property/propertiesSystem.js index a022582e..372761ab 100644 --- a/test/integration/property/propertiesSystem.js +++ b/test/integration/property/propertiesSystem.js @@ -56,6 +56,16 @@ describe('System', function testSystem() { 'Sunday\nMonday\nTuesday', 'Welcome to the BIG-IP Configuration Utility.\n\nLog in with your username and password using the fields on the left.' ] + }, + { + name: 'usernamePrompt', + inputValue: [undefined, 'Your username:', undefined], + expectedValue: ['Username', 'Your username:', 'Username'] + }, + { + name: 'passwordPrompt', + inputValue: [undefined, 'Your password:', undefined], + expectedValue: ['Password', 'Your password:', 'Password'] } ]; diff --git a/test/integration/setup.js b/test/integration/setup.js index fecff4b7..3e4ffdf4 100644 --- a/test/integration/setup.js +++ b/test/integration/setup.js @@ -85,7 +85,6 @@ function setupMachines(harnessInfo) { const ipAddress = machine.admin_ip; return scpRpm(ipAddress, username, password) .then(() => installRpm(ipAddress, adminUsername, adminPassword)) - .then(JSON.parse) .then((response) => { if (response.status === 'CREATED') { return waitForDo(ipAddress, adminUsername, adminPassword); diff --git a/test/integration/test.js b/test/integration/test.js index c1aaf2ad..8f6f0391 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -260,7 +260,7 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.sendRequest(options, retryOptions); }) .then((response) => { - const dns = JSON.parse(response.body); + const dns = response.body; originalDns = { nameServers: dns.nameServers, search: dns.search @@ -471,7 +471,8 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr prefix: '1111:2222::/127', prefixLenRange: '128' } - ] + ], + routeDomain: '0' }, testRoutingPrefixList2: { name: 'testRoutingPrefixList2', @@ -482,7 +483,8 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr prefix: '10.3.3.0/24', prefixLenRange: '30:32' } - ] + ], + routeDomain: '0' } } )); @@ -1118,12 +1120,11 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.sendRequest(options, retryOptions); }) .then((response) => { - if (response.response.statusCode !== constants.HTTP_SUCCESS) { + if (response.statusCode !== constants.HTTP_SUCCESS) { throw new Error('could not check revoking'); } return response.body; }) - .then(JSON.parse) .then((assignment) => { assert.strictEqual(assignment.status, 'REVOKED'); }) @@ -1158,12 +1159,11 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.sendRequest(options, retryOptions); }) .then((response) => { - if (response.response.statusCode !== constants.HTTP_ACCEPTED) { + if (response.statusCode !== constants.HTTP_ACCEPTED) { throw new Error('could not request to revoke license'); } return response.body; }) - .then(JSON.parse) .then((response) => { logger.info(`Expecting STARTED. Got ${response.status}`); assert.strictEqual(response.status, 'STARTED'); @@ -1178,19 +1178,19 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.sendRequest(options, retryOptions); }) .then((response) => { - logger.debug(`Audit status code ${response.response.statusCode}`); - if (response.response.statusCode === constants.HTTP_SUCCESS) { + logger.debug(`Audit status code ${response.statusCode}`); + if (response.statusCode === constants.HTTP_SUCCESS) { logger.debug('Got success status for GET request'); - logger.debug(`Looking for REVOKED. Got ${JSON.parse(response.body).status}`); - if (JSON.parse(response.body).status === 'REVOKED') { + logger.debug(`Looking for REVOKED. Got ${response.body.status}`); + if (response.body.status === 'REVOKED') { logger.debug('resolving retry func'); return Promise.resolve(); } logger.debug('rejecting retry func for status'); - throw new Error(JSON.parse(response.body).status); + throw new Error(response.body.status); } else { logger.debug('rejecting retry func for status code'); - throw new Error(response.response.statusCode); + throw new Error(response.statusCode); } }) .catch((err) => { @@ -1246,7 +1246,6 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.testRequest( null, `${common.hostname(thisMachine.ip, constants.PORT)}${inspectEndpoint}`, authData, constants.HTTP_SUCCESS, 'GET' ) - .then(JSON.parse) .then((body) => { assert.notStrictEqual(body[0].declaration, undefined, 'Should have "declaration" property'); }); @@ -1260,7 +1259,6 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr return common.testRequest( null, `${common.hostname(thisMachine.ip, constants.PORT)}${inspectEndpoint}`, authData, constants.HTTP_SUCCESS, 'GET' ) - .then(JSON.parse) .then((body) => { originDeclaration = body[0].declaration; originDeclaration.declaration.async = true; // Timing issue without async @@ -1275,7 +1273,6 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr .then(() => common.testRequest( null, `${common.hostname(thisMachine.ip, constants.PORT)}${inspectEndpoint}`, authData, constants.HTTP_SUCCESS, 'GET' )) - .then(JSON.parse) .then((body) => { // declaration should be the same const declaration = body[0].declaration; @@ -1311,7 +1308,6 @@ describe('Declarative Onboarding Integration Test Suite', function performIntegr 'GET', 1 ) - .then(JSON.parse) .then((body) => { logger.debug(`Got example ${JSON.stringify(body)}`); assert.notStrictEqual(body.Common, undefined); @@ -1349,12 +1345,11 @@ function getF5Token(deviceIp, auth) { return common.sendRequest(options, retryOptions); }) .then((response) => { - if (response.response.statusCode !== constants.HTTP_SUCCESS) { + if (response.statusCode !== constants.HTTP_SUCCESS) { throw new Error('could not get token'); } return response.body; }) - .then(JSON.parse) .then((response) => Promise.resolve(response.token.token)); } @@ -1384,12 +1379,11 @@ function getAuditLink(bigIqAddress, bigIpAddress, bigIqAuth) { return common.sendRequest(options, retryOptions) .then((response) => { logger.info(`get assignments response ${JSON.stringify(response)}`); - if (response.response.statusCode !== constants.HTTP_SUCCESS) { + if (response.statusCode !== constants.HTTP_SUCCESS) { return Promise.reject(new Error('could not license')); } return response.body; }) - .then((response) => JSON.parse(response)) .then((response) => response.items) .then((assignments) => { logger.debug(`current assignments: ${JSON.stringify( diff --git a/test/unit/lib/configManagerTests.js b/test/unit/lib/configManagerTests.js index 36fabea5..6019a40b 100644 --- a/test/unit/lib/configManagerTests.js +++ b/test/unit/lib/configManagerTests.js @@ -2674,7 +2674,8 @@ describe('configManager', () => { name: 'examplePrefixList', entriesReference: { link: 'https://localhost/mgmt/tm/net/routing/prefix-list/~Common~examplePrefixList/entries?ver=14.1.2' - } + }, + routeDomain: '/Common/testRouteDomain' } ]; listResponses['/tm/net/routing/prefix-list/~Common~examplePrefixList/entries'] = [ @@ -2711,7 +2712,8 @@ describe('configManager', () => { prefix: '1111:2222:3333:4444::/64', prefixLenRange: '24:28' } - ] + ], + routeDomain: 'testRouteDomain' } }); }); diff --git a/test/unit/lib/declarationHandlerTests.js b/test/unit/lib/declarationHandlerTests.js index 5d406655..54a5a693 100644 --- a/test/unit/lib/declarationHandlerTests.js +++ b/test/unit/lib/declarationHandlerTests.js @@ -3644,6 +3644,87 @@ describe('declarationHandler', () => { assert.deepStrictEqual(state.currentConfig.Common.FirewallPortList, undefined); }); }); + + it('should apply SecurityWaf fixes', () => { + const newDeclaration = { + parsed: true, + Common: { + SecurityWaf: { + antiVirusProtection: { + guaranteeEnforcement: true, + hostname: 'do.test', + port: 123 + }, + advancedSettings: [ + { + name: 'max_raw_request_len', + value: '1000' + } + ] + } + } + }; + const state = { + originalConfig: { + Common: { + SecurityWaf: { + antiVirusProtection: { + guaranteeEnforcement: true, + hostname: '', + port: 1344 + }, + advancedSettings: { + cookie_max_age: { + id: '1XJcDTbBxqP0GtOcdQzF0g', + value: '0' + }, + max_raw_request_len: { + id: 'AG4WUXljvu9lM6AH8dAKXg', + value: '10000' + }, + single_page_application: { + id: 'GqhjvcKleDusK8-xl1lC4w', + value: '0' + } + } + } + } + }, + currentConfig: { + parsed: true, + Common: {} + } + }; + + const declarationHandler = new DeclarationHandler(bigIpMock, null, state); + return declarationHandler.process(newDeclaration) + .then(() => { + assert.deepStrictEqual( + declarationWithDefaults.Common.SecurityWaf, + { + antiVirusProtection: { + guaranteeEnforcement: true, + hostname: 'do.test', + port: 123 + }, + advancedSettings: { + cookie_max_age: { + id: '1XJcDTbBxqP0GtOcdQzF0g', + value: '0' + }, + max_raw_request_len: { + id: 'AG4WUXljvu9lM6AH8dAKXg', + value: '1000' + }, + single_page_application: { + id: 'GqhjvcKleDusK8-xl1lC4w', + value: '0' + } + } + } + ); + }); + }); }); describe('AVR dependencies', () => { diff --git a/test/unit/lib/deleteHandlerTests.js b/test/unit/lib/deleteHandlerTests.js index 27412070..ded0fe4a 100644 --- a/test/unit/lib/deleteHandlerTests.js +++ b/test/unit/lib/deleteHandlerTests.js @@ -814,7 +814,7 @@ describe(('deleteHandler'), function testDeleteHandler() { }); }); - it('should delete RouteMap, RoutingAccessList, RoutingAsPath, and RoutePrefixList in that order', () => { + it('should delete RouteMap, RoutePrefixList, RouteDomain, RoutingAccessList, and RoutingAsPath in that order', () => { const state = { currentConfig: { Common: { @@ -823,6 +823,9 @@ describe(('deleteHandler'), function testDeleteHandler() { asLocal: 1 } }, + RouteDomain: { + routeDomainTest: {} + }, RouteMap: { routeMapTest: { name: 44, @@ -875,7 +878,8 @@ describe(('deleteHandler'), function testDeleteHandler() { prefix: '10.3.3.0/24', prefixLenRange: 32 } - ] + ], + routeDomain: 'routeDomainTest' } } } @@ -884,17 +888,20 @@ describe(('deleteHandler'), function testDeleteHandler() { const declaration = { Common: { + RouteDomain: { + routeDomainTest: {} + }, + RouteMap: { + routeMapTest: {} + }, RoutingAccessList: { routingAccessListTest: {} }, - RoutingBGP: { - routingBgpTest: {} - }, RoutingAsPath: { routingAsPathTest: {} }, - RouteMap: { - routeMapTest: {} + RoutingBGP: { + routingBgpTest: {} }, RoutingPrefixList: { routingPrefixListTest: {} @@ -905,11 +912,12 @@ describe(('deleteHandler'), function testDeleteHandler() { const deleteHandler = new DeleteHandler(declaration, bigIpMock, undefined, state); return deleteHandler.process() .then(() => { - assert.strictEqual(deletedPaths.length, 4); + assert.strictEqual(deletedPaths.length, 5); assert.strictEqual(deletedPaths[0], '/tm/net/routing/route-map/~Common~routeMapTest'); - assert.strictEqual(deletedPaths[1], '/tm/net/routing/access-list/~Common~routingAccessListTest'); - assert.strictEqual(deletedPaths[2], '/tm/net/routing/as-path/~Common~routingAsPathTest'); - assert.strictEqual(deletedPaths[3], '/tm/net/routing/prefix-list/~Common~routingPrefixListTest'); + assert.strictEqual(deletedPaths[1], '/tm/net/routing/prefix-list/~Common~routingPrefixListTest'); + assert.strictEqual(deletedPaths[2], '/tm/net/route-domain/~Common~routeDomainTest'); + assert.strictEqual(deletedPaths[3], '/tm/net/routing/access-list/~Common~routingAccessListTest'); + assert.strictEqual(deletedPaths[4], '/tm/net/routing/as-path/~Common~routingAsPathTest'); }); }); diff --git a/test/unit/lib/inspectHandlerTests.js b/test/unit/lib/inspectHandlerTests.js index c5270b5e..8285349a 100644 --- a/test/unit/lib/inspectHandlerTests.js +++ b/test/unit/lib/inspectHandlerTests.js @@ -512,7 +512,9 @@ describe('inspectHandler', () => { guiAudit: 'disabled', mgmtDhcp: 'enabled', guiSecurityBanner: 'enabled', - guiSecurityBannerText: 'This is the gui security banner text.' + guiSecurityBannerText: 'This is the gui security banner text.', + usernamePrompt: 'Username', + passwordPrompt: 'Password' }, '/tm/cli/global-settings': { idleTimeout: 'disabled', @@ -725,7 +727,8 @@ describe('inspectHandler', () => { name: 'examplePrefixList', entriesReference: { link: 'https://localhost/mgmt/tm/net/routing/prefix-list/~Common~examplePrefixList/entries?ver=14.1.2' - } + }, + routeDomain: 'testRouteDomain' } ], '/tm/net/routing/prefix-list/~Common~examplePrefixList/entries': [ @@ -1723,7 +1726,24 @@ describe('inspectHandler', () => { }, publisher: 'none', smtpConfig: 'none' - } + }, + '/tm/asm/virus-detection-server': { + guaranteeEnforcement: false, + hostname: 'do.test', + port: 123 + }, + '/tm/asm/advanced-settings': [ + { + id: 'id0', + name: 'policy_history_max_total_size', + value: 1000 + }, + { + id: 'id1', + name: 'max_json_policy_size', + value: 1000 + } + ] }); // PURPOSE: to be sure that all properties (we are expecting) are here @@ -1919,7 +1939,8 @@ describe('inspectHandler', () => { prefix: '1111:2222:3333:4444::/64', prefixLengthRange: '24:28' } - ] + ], + routeDomain: 'testRouteDomain' }, exampleRouteMap: { class: 'RouteMap', @@ -2273,7 +2294,9 @@ describe('inspectHandler', () => { preserveOrigDhcpRoutes: true, mgmtDhcpEnabled: true, guiSecurityBanner: true, - guiSecurityBannerText: 'This is the gui security banner text.' + guiSecurityBannerText: 'This is the gui security banner text.', + usernamePrompt: 'Username', + passwordPrompt: 'Password' }, currentTrafficControl: { class: 'TrafficControl', @@ -2713,6 +2736,24 @@ describe('inspectHandler', () => { collectStaleRulesEnabled: false, publisher: 'none', smtpConfig: 'none' + }, + currentSecurityWaf: { + class: 'SecurityWaf', + antiVirusProtection: { + guaranteeEnforcementEnabled: false, + hostname: 'do.test', + port: 123 + }, + advancedSettings: [ + { + name: 'policy_history_max_total_size', + value: 1000 + }, + { + name: 'max_json_policy_size', + value: 1000 + } + ] } } } diff --git a/test/unit/lib/networkHandlerTests.js b/test/unit/lib/networkHandlerTests.js index 21dfb444..92b03a96 100644 --- a/test/unit/lib/networkHandlerTests.js +++ b/test/unit/lib/networkHandlerTests.js @@ -1825,6 +1825,12 @@ describe('networkHandler', () => { }); it('should send out 1 enable value to the sys/db/...routing endpoint if a declaration includes RoutingPrefixList', () => { + const state = { + currentConfig: { + Common: {} + } + }; + const declaration = { Common: { RoutingPrefixList: { @@ -1860,7 +1866,7 @@ describe('networkHandler', () => { } }; - const networkHandler = new NetworkHandler(declaration, bigIpMock); + const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); return networkHandler.process() .then(() => { const data = dataSent['/tm/sys/db/tmrouted.tmos.routing']; @@ -2343,12 +2349,25 @@ describe('networkHandler', () => { }); describe('RoutingPrefixList', () => { + let state; + let bigIpMockSpy; + + beforeEach(() => { + bigIpMockSpy = sinon.spy(bigIpMock); + state = { + currentConfig: { + Common: {} + } + }; + }); + it('should handle a fully specified Routing Prefix List', () => { const declaration = { Common: { RoutingPrefixList: { RoutingPrefixList1: { name: 'RoutingPrefixList1', + routeDomain: 'testRouteDomain', entries: [ { name: 10, @@ -2360,6 +2379,7 @@ describe('networkHandler', () => { }, RoutingPrefixList2: { name: 'RoutingPrefixList2', + routeDomain: 'testRouteDomain2', entries: [ { name: 20, @@ -2379,13 +2399,14 @@ describe('networkHandler', () => { } }; - const networkHandler = new NetworkHandler(declaration, bigIpMock); + const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); return networkHandler.process() .then(() => { const data = dataSent[PATHS.RoutingPrefixList]; assert.deepStrictEqual(data[0], { name: 'RoutingPrefixList1', partition: 'Common', + routeDomain: 'testRouteDomain', entries: { 10: { action: 'permit', @@ -2397,6 +2418,7 @@ describe('networkHandler', () => { assert.deepStrictEqual(data[1], { name: 'RoutingPrefixList2', partition: 'Common', + routeDomain: 'testRouteDomain2', entries: { 20: { action: 'permit', @@ -2419,23 +2441,120 @@ describe('networkHandler', () => { RoutingPrefixList: { RoutingPrefixList1: { name: 'RoutingPrefixList1', + routeDomain: '0', entries: [] } } } }; - const networkHandler = new NetworkHandler(declaration, bigIpMock); + const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); return networkHandler.process() .then(() => { const data = dataSent[PATHS.RoutingPrefixList]; assert.deepStrictEqual(data[0], { name: 'RoutingPrefixList1', partition: 'Common', + routeDomain: '0', entries: {} }); }); }); + + it('should delete first if routeDomain changes', () => { + state = { + currentConfig: { + Common: { + RoutingPrefixList: { + RoutingPrefixList1: { + name: 'RoutingPrefixList1', + entries: [], + routeDomain: '0' + } + } + } + } + }; + + const declaration = { + Common: { + RoutingPrefixList: { + RoutingPrefixList1: { + name: 'RoutingPrefixList1', + entries: [], + routeDomain: '1' + } + } + } + }; + + const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); + return networkHandler.process() + .then(() => { + const data = dataSent[PATHS.RoutingPrefixList]; + assert.deepStrictEqual(data[0], { + name: 'RoutingPrefixList1', + partition: 'Common', + routeDomain: '1' + }); + assert.deepStrictEqual(data[1], { + name: 'RoutingPrefixList1', + partition: 'Common', + entries: {} + }); + // modify enables /tm/sys/db/tmrouted.tmos.routing + assert.strictEqual(bigIpMockSpy.modify.callCount, 1); + assert.strictEqual(bigIpMock.transaction.callCount, 1); + // delete comes from the first command in the transaction + assert.strictEqual(bigIpMock.delete.callCount, 1); + // create comes from the second command in the transaction + assert.strictEqual(bigIpMockSpy.create.callCount, 1); + // createOrModify comes immediately after the transaction + assert.strictEqual(bigIpMockSpy.createOrModify.callCount, 1); + }); + }); + + it('should not delete if routeDomain unchanged', () => { + state = { + currentConfig: { + Common: { + RoutingPrefixList: { + RoutingPrefixList1: { + name: 'RoutingPrefixList1', + entries: [], + routeDomain: '1' + } + } + } + } + }; + + const declaration = { + Common: { + RoutingPrefixList: { + RoutingPrefixList1: { + name: 'RoutingPrefixList1', + entries: [], + routeDomain: '1' + } + } + } + }; + + const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); + return networkHandler.process() + .then(() => { + const data = dataSent[PATHS.RoutingPrefixList]; + assert.deepStrictEqual(data[0], { + name: 'RoutingPrefixList1', + partition: 'Common', + entries: {}, + routeDomain: '1' + }); + assert.strictEqual(bigIpMockSpy.delete.callCount, 0); + assert.strictEqual(bigIpMockSpy.createOrModify.callCount, 1); + }); + }); }); describe('RouteMap', () => { @@ -2665,10 +2784,21 @@ describe('networkHandler', () => { assert.deepStrictEqual(data[0], { name: 'RouteMap1', partition: 'Common', - entries: {}, routeDomain: '1' }); - assert.strictEqual(bigIpMockSpy.delete.callCount, 1); + assert.deepStrictEqual(data[1], { + name: 'RouteMap1', + partition: 'Common', + entries: {} + }); + // modify enables /tm/sys/db/tmrouted.tmos.routing + assert.strictEqual(bigIpMockSpy.modify.callCount, 1); + assert.strictEqual(bigIpMock.transaction.callCount, 1); + // delete comes from the first command in the transaction + assert.strictEqual(bigIpMock.delete.callCount, 1); + // create comes from the second command in the transaction + assert.strictEqual(bigIpMockSpy.create.callCount, 1); + // createOrModify comes immediately after the transaction assert.strictEqual(bigIpMockSpy.createOrModify.callCount, 1); }); }); @@ -2723,116 +2853,6 @@ describe('networkHandler', () => { bigIpMockSpy = sinon.spy(bigIpMock); }); - it('should handle combined RouteMap and RoutingBGP with changing route domain', () => { - const state = { - currentConfig: { - Common: { - RouteMap: { - routeMapIn: { - name: 'routeMapIn', - entries: [], - routeDomain: 'zero' - }, - routeMapOut: { - name: 'routeMapOut', - entries: [], - routeDomain: 'zero' - } - }, - RoutingBGP: { - routingBgp: { - name: 'routingBgp', - peerGroups: [ - { - name: 'Neighbor_IN', - addressFamily: [ - { - name: 'ipv4', - routeMap: { - in: 'routeMapIn', - out: 'routeMapOut' - }, - softReconfigurationInbound: 'enabled' - } - ], - remoteAs: 65020 - } - ], - routeDomain: 'zero' - } - } - } - } - }; - - const declaration = { - Common: { - RouteMap: { - routeMapIn: { - name: 'routeMapIn', - entries: [], - routeDomain: 'one' - }, - routeMapOut: { - name: 'routeMapOut', - entries: [], - routeDomain: 'one' - } - }, - RoutingBGP: { - routingBgp: { - name: 'routingBgp', - peerGroups: [ - { - name: 'Neighbor_IN', - addressFamily: [ - { - name: 'ipv4', - routeMap: { - in: 'routeMapIn', - out: 'routeMapOut' - }, - softReconfigurationInbound: 'enabled' - } - ], - remoteAs: 65020 - } - ], - routeDomain: 'one' - } - } - } - }; - - const networkHandler = new NetworkHandler(declaration, bigIpMock, null, state); - return networkHandler.process() - .then(() => { - assert.strictEqual(all[0].action, 'delete'); - assert.strictEqual(all[0].path, '/tm/net/routing/bgp/~Common~routingBgp'); - - assert.strictEqual(all[1].action, 'delete'); - assert.strictEqual(all[1].path, '/tm/net/routing/route-map/~Common~routeMapIn'); - - assert.strictEqual(all[2].action, 'delete'); - assert.strictEqual(all[2].path, '/tm/net/routing/route-map/~Common~routeMapOut'); - - assert.strictEqual(all[3].action, 'createOrModify'); - assert.strictEqual(all[3].path, '/tm/net/routing/route-map'); - assert.strictEqual(all[3].data.name, 'routeMapIn'); - assert.strictEqual(all[3].data.routeDomain, 'one'); - - assert.strictEqual(all[4].action, 'createOrModify'); - assert.strictEqual(all[4].path, '/tm/net/routing/route-map'); - assert.strictEqual(all[4].data.name, 'routeMapOut'); - assert.strictEqual(all[4].data.routeDomain, 'one'); - - assert.strictEqual(all[5].action, 'createOrModify'); - assert.strictEqual(all[5].path, '/tm/net/routing/bgp'); - assert.strictEqual(all[5].data.name, 'routingBgp'); - assert.strictEqual(all[5].data.routeDomain, 'one'); - }); - }); - it('should handle a fully specified RoutingBGP', () => { const state = { currentConfig: { diff --git a/test/unit/lib/routingPrefixListValidatorTests.js b/test/unit/lib/routingPrefixListValidatorTests.js index 1b8da3a6..80154714 100644 --- a/test/unit/lib/routingPrefixListValidatorTests.js +++ b/test/unit/lib/routingPrefixListValidatorTests.js @@ -43,7 +43,8 @@ describe('routingPrefixListValidator', () => { prefix: '1111:2222:3333:4444:5555:6666:7777:8888/127', prefixLengthRange: '128' } - ] + ], + routeDomain: 'testRouteDomain' }, exampleRoutingPrefixList2: { class: 'RoutingPrefixList', @@ -60,7 +61,8 @@ describe('routingPrefixListValidator', () => { prefix: '10.4.4.0/23', prefixLengthRange: '24' } - ] + ], + routeDomain: 'testRouteDomain' } } } diff --git a/test/unit/lib/securityHandlerTests.js b/test/unit/lib/securityHandlerTests.js index 9d736bd7..06b03d29 100644 --- a/test/unit/lib/securityHandlerTests.js +++ b/test/unit/lib/securityHandlerTests.js @@ -25,6 +25,7 @@ const sinon = require('sinon'); const PATHS = require('../../../src/lib/sharedConstants').PATHS; const Logger = require('../../../src/lib/logger'); +const doUtil = require('../../../src/lib/doUtil'); const SecurityHandler = require('../../../src/lib/securityHandler'); describe('SecurityHandler', () => { @@ -149,4 +150,79 @@ describe('SecurityHandler', () => { }); }); }); + + describe('SecurityWaf', () => { + it('should handle SecurityWaf', () => { + sinon.stub(doUtil, 'restartService').resolves(); + const declaration = { + Common: { + SecurityWaf: { + antiVirusProtection: { + guarenteeEnforcement: true, + hostname: 'do.test', + port: 123 + }, + advancedSettings: { + cookie_expiration_time_out: { + value: '1000' + }, + max_json_policy_size: { + value: '10000' + }, + single_page_application: { + value: '1' + } + } + } + } + }; + const state = { + id: 'stateId' + }; + + const securityHandler = new SecurityHandler(declaration, bigIpMock, undefined, state); + return securityHandler.process() + .then(() => { + console.log(dataSent); + const antivirusProtection = dataSent[PATHS.AntiVirusProtection]; + const setting0 = dataSent[`${PATHS.WafAdvancedSettings}/Bo68NqP9roUE8Vv2NO-29Q`]; + const setting1 = dataSent[`${PATHS.WafAdvancedSettings}/4NRiSGFR-qvXsN8VM7oKiw`]; + const setting2 = dataSent[`${PATHS.WafAdvancedSettings}/GqhjvcKleDusK8-xl1lC4w`]; + assert.deepStrictEqual( + antivirusProtection, + [ + { + guarenteeEnforcement: true, + hostname: 'do.test', + port: 123 + } + ] + ); + assert.deepStrictEqual( + setting0, + [ + { + value: '1000' + } + ] + ); + assert.deepStrictEqual( + setting1, + [ + { + value: '10000' + } + ] + ); + assert.deepStrictEqual( + setting2, + [ + { + value: '1' + } + ] + ); + }); + }); + }); }); diff --git a/test/unit/lib/systemHandlerTests.js b/test/unit/lib/systemHandlerTests.js index 77170b76..356ee1b9 100644 --- a/test/unit/lib/systemHandlerTests.js +++ b/test/unit/lib/systemHandlerTests.js @@ -861,6 +861,26 @@ describe('systemHandler', () => { }); }); + it('should handle usernamePrompt and passwordPrompt', () => { + const declaration = { + Common: { + System: { + usernamePrompt: 'Your username:', + passwordPrompt: 'Your password:' + } + } + }; + + const systemHandler = new SystemHandler(declaration, bigIpMock, null, state); + return systemHandler.process() + .then(() => { + assert.deepStrictEqual( + dataSent[PATHS.SysGlobalSettings][0], + { usernamePrompt: 'Your username:', passwordPrompt: 'Your password:' } + ); + }); + }); + it('should handle root users without keys', () => { // Stubs out the remote call to confirm the key is not added to the user doUtilExecuteBashCommandStub.restore(); diff --git a/test/unit/schema/networkSchemaTests.js b/test/unit/schema/networkSchemaTests.js index eac904c5..eda9f85c 100644 --- a/test/unit/schema/networkSchemaTests.js +++ b/test/unit/schema/networkSchemaTests.js @@ -1925,7 +1925,8 @@ describe('network.schema.json', () => { prefix: '1111:2222:3333:4444::/64', prefixLengthRange: '1:128' } - ] + ], + routeDomain: 'testRouteDomain' }; assert.ok(validate(data), getErrorString(validate)); diff --git a/test/unit/schema/securitySchemaTests.js b/test/unit/schema/securitySchemaTests.js index 5578de8f..d12d4ee9 100644 --- a/test/unit/schema/securitySchemaTests.js +++ b/test/unit/schema/securitySchemaTests.js @@ -99,6 +99,71 @@ describe('security.schema.json', () => { }); }); }); + + it('SecurityWaf', () => { + describe('valid', () => { + it('should validate minimal data', () => { + const data = { + class: 'SecurityWaf' + }; + assert.ok(validate(data), getErrorString(validate)); + }); + + it('should validate all properties and mutliple advanced settings', () => { + const data = { + antiVirusProtection: { + guaranteeenforcementEnabled: true, + hostname: 'do.test', + port: 123 + }, + advancedSettings: [ + { + name: 'long_request_buffer_size', + value: 1000 + }, + { + name: 'send_content_events', + value: 1 + }, + { + name: 'ecard_regexp_decimal', + value: 'string' + } + ] + }; + assert.ok(validate(data), getErrorString(validate)); + }); + }); + + describe('invalid', () => { + it('should invalidate additional properties', () => { + const data = { + class: 'SecurityWaf', + invalidProperty: '' + }; + assert.strictEqual(validate(data), false, 'additional properties should not be valid'); + assert(getErrorString().includes('"additionalProperty": "invalidProperty"')); + }); + + it('should invalidate a string used for an integer setting', () => { + const data = { + class: 'SecurityWaf', + advancedSettings: [ + { + name: 'long_request_buffer_size', + value: 'invalid' + }, + { + name: 'send_content_events', + value: 1 + } + ] + }; + assert.strictEqual(validate(data), false, 'should be integer'); + assert(getErrorString().includes('should be integer')); + }); + }); + }); }); function getErrorString() { diff --git a/test/unit/schema/systemSchemaTests.js b/test/unit/schema/systemSchemaTests.js index 3b330891..2d182462 100644 --- a/test/unit/schema/systemSchemaTests.js +++ b/test/unit/schema/systemSchemaTests.js @@ -1062,7 +1062,9 @@ describe('system.schema.json', () => { "consoleInactivityTimeout": 50, "cliInactivityTimeout": 60, "preserveOrigDhcpRoutes": true, - "mgmtDhcpEnabled": true + "mgmtDhcpEnabled": true, + "usernamePrompt": "Your username:", + "passwordPrompt": "Your password:" }; assert.ok(validate(data), getErrorString(validate)); }); diff --git a/versions.json b/versions.json index 34baf7d9..f09943f0 100644 --- a/versions.json +++ b/versions.json @@ -1,7 +1,7 @@ { "versionMetaTimestamp": 1540928503, "latestVersion": { - "name": "1.39 (non-LTS)", + "name": "1.40 (non-LTS)", "url": "/products/extensions/f5-declarative-onboarding/latest/" }, "otherVersions": [