@microsoft/terraform-cdk-constructs 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +54846 -26661
- package/API.md +72091 -23784
- package/lib/azure-actiongroup/index.d.ts +0 -10
- package/lib/azure-actiongroup/index.js +1 -11
- package/lib/azure-actiongroup/lib/action-group.d.ts +0 -10
- package/lib/azure-actiongroup/lib/action-group.js +6 -32
- package/lib/azure-actiongroup/lib/index.d.ts +1 -4
- package/lib/azure-actiongroup/lib/index.js +2 -5
- package/lib/azure-activitylogalert/index.d.ts +0 -10
- package/lib/azure-activitylogalert/index.js +1 -11
- package/lib/azure-activitylogalert/lib/activity-log-alert.d.ts +0 -10
- package/lib/azure-activitylogalert/lib/activity-log-alert.js +6 -32
- package/lib/azure-activitylogalert/lib/index.d.ts +1 -4
- package/lib/azure-activitylogalert/lib/index.js +2 -5
- package/lib/azure-aks/index.d.ts +0 -8
- package/lib/azure-aks/index.js +1 -11
- package/lib/azure-aks/lib/aks-cluster.d.ts +4 -13
- package/lib/azure-aks/lib/aks-cluster.js +13 -36
- package/lib/azure-aks/lib/index.d.ts +1 -10
- package/lib/azure-aks/lib/index.js +2 -21
- package/lib/azure-diagnosticsettings/index.d.ts +0 -6
- package/lib/azure-diagnosticsettings/index.js +1 -7
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings.d.ts +0 -10
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +6 -32
- package/lib/azure-diagnosticsettings/lib/index.d.ts +1 -7
- package/lib/azure-diagnosticsettings/lib/index.js +2 -8
- package/lib/azure-dnsforwardingruleset/index.d.ts +1 -0
- package/lib/azure-dnsforwardingruleset/index.js +18 -0
- package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.d.ts +24 -0
- package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.js +206 -0
- package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.d.ts +174 -0
- package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +214 -0
- package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.d.ts +24 -0
- package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.js +242 -0
- package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.d.ts +193 -0
- package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +193 -0
- package/lib/azure-dnsforwardingruleset/lib/index.d.ts +6 -0
- package/lib/azure-dnsforwardingruleset/lib/index.js +23 -0
- package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.d.ts +24 -0
- package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.js +199 -0
- package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.d.ts +160 -0
- package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +178 -0
- package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.d.ts +9 -0
- package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.js +133 -0
- package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.d.ts +9 -0
- package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.js +350 -0
- package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.d.ts +9 -0
- package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.js +397 -0
- package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.d.ts +9 -0
- package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.js +285 -0
- package/lib/azure-dnsresolver/index.d.ts +1 -0
- package/lib/azure-dnsresolver/index.js +18 -0
- package/lib/azure-dnsresolver/lib/dns-resolver-schemas.d.ts +24 -0
- package/lib/azure-dnsresolver/lib/dns-resolver-schemas.js +218 -0
- package/lib/azure-dnsresolver/lib/dns-resolver.d.ts +170 -0
- package/lib/azure-dnsresolver/lib/dns-resolver.js +236 -0
- package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.d.ts +24 -0
- package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.js +261 -0
- package/lib/azure-dnsresolver/lib/inbound-endpoint.d.ts +189 -0
- package/lib/azure-dnsresolver/lib/inbound-endpoint.js +243 -0
- package/lib/azure-dnsresolver/lib/index.d.ts +6 -0
- package/lib/azure-dnsresolver/lib/index.js +23 -0
- package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.d.ts +24 -0
- package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.js +231 -0
- package/lib/azure-dnsresolver/lib/outbound-endpoint.d.ts +175 -0
- package/lib/azure-dnsresolver/lib/outbound-endpoint.js +234 -0
- package/lib/azure-dnsresolver/test/dns-resolver.integ.d.ts +14 -0
- package/lib/azure-dnsresolver/test/dns-resolver.integ.js +117 -0
- package/lib/azure-dnsresolver/test/dns-resolver.spec.d.ts +9 -0
- package/lib/azure-dnsresolver/test/dns-resolver.spec.js +353 -0
- package/lib/azure-dnsresolver/test/inbound-endpoint.integ.d.ts +9 -0
- package/lib/azure-dnsresolver/test/inbound-endpoint.integ.js +151 -0
- package/lib/azure-dnsresolver/test/inbound-endpoint.spec.d.ts +9 -0
- package/lib/azure-dnsresolver/test/inbound-endpoint.spec.js +441 -0
- package/lib/azure-dnsresolver/test/outbound-endpoint.integ.d.ts +9 -0
- package/lib/azure-dnsresolver/test/outbound-endpoint.integ.js +149 -0
- package/lib/azure-dnsresolver/test/outbound-endpoint.spec.d.ts +9 -0
- package/lib/azure-dnsresolver/test/outbound-endpoint.spec.js +301 -0
- package/lib/azure-dnszone/index.d.ts +1 -0
- package/lib/azure-dnszone/index.js +18 -0
- package/lib/azure-dnszone/lib/dns-zone-schemas.d.ts +24 -0
- package/lib/azure-dnszone/lib/dns-zone-schemas.js +191 -0
- package/lib/azure-dnszone/lib/dns-zone.d.ts +182 -0
- package/lib/azure-dnszone/lib/dns-zone.js +228 -0
- package/lib/azure-dnszone/lib/index.d.ts +2 -0
- package/lib/azure-dnszone/lib/index.js +19 -0
- package/lib/azure-dnszone/test/dns-zone.integ.d.ts +9 -0
- package/lib/azure-dnszone/test/dns-zone.integ.js +85 -0
- package/lib/azure-dnszone/test/dns-zone.spec.d.ts +9 -0
- package/lib/azure-dnszone/test/dns-zone.spec.js +285 -0
- package/lib/azure-metricalert/index.d.ts +0 -10
- package/lib/azure-metricalert/index.js +1 -11
- package/lib/azure-metricalert/lib/index.d.ts +1 -4
- package/lib/azure-metricalert/lib/index.js +2 -5
- package/lib/azure-metricalert/lib/metric-alert.d.ts +0 -10
- package/lib/azure-metricalert/lib/metric-alert.js +6 -32
- package/lib/azure-networkinterface/index.d.ts +0 -3
- package/lib/azure-networkinterface/index.js +1 -4
- package/lib/azure-networkinterface/lib/index.d.ts +1 -5
- package/lib/azure-networkinterface/lib/index.js +2 -5
- package/lib/azure-networkinterface/lib/network-interface.d.ts +4 -9
- package/lib/azure-networkinterface/lib/network-interface.js +14 -29
- package/lib/azure-networkinterface/test/network-interface.integ.js +20 -6
- package/lib/azure-networksecuritygroup/index.d.ts +0 -5
- package/lib/azure-networksecuritygroup/index.js +1 -6
- package/lib/azure-networksecuritygroup/lib/index.d.ts +2 -5
- package/lib/azure-networksecuritygroup/lib/index.js +17 -14
- package/lib/azure-networksecuritygroup/lib/network-security-group.d.ts +4 -13
- package/lib/azure-networksecuritygroup/lib/network-security-group.js +14 -36
- package/lib/azure-policyassignment/index.d.ts +1 -0
- package/lib/azure-policyassignment/index.js +18 -0
- package/lib/azure-policyassignment/lib/index.d.ts +2 -0
- package/lib/azure-policyassignment/lib/index.js +19 -0
- package/lib/azure-policyassignment/lib/policy-assignment-schemas.d.ts +25 -0
- package/lib/azure-policyassignment/lib/policy-assignment-schemas.js +260 -0
- package/lib/azure-policyassignment/lib/policy-assignment.d.ts +342 -0
- package/lib/azure-policyassignment/lib/policy-assignment.js +228 -0
- package/lib/azure-policyassignment/test/policy-assignment.integ.d.ts +13 -0
- package/lib/azure-policyassignment/test/policy-assignment.integ.js +153 -0
- package/lib/azure-policyassignment/test/policy-assignment.spec.d.ts +9 -0
- package/lib/azure-policyassignment/test/policy-assignment.spec.js +651 -0
- package/lib/azure-policydefinition/index.d.ts +1 -0
- package/lib/azure-policydefinition/index.js +18 -0
- package/lib/azure-policydefinition/lib/index.d.ts +2 -0
- package/lib/azure-policydefinition/lib/index.js +19 -0
- package/lib/azure-policydefinition/lib/policy-definition-schemas.d.ts +25 -0
- package/lib/azure-policydefinition/lib/policy-definition-schemas.js +210 -0
- package/lib/azure-policydefinition/lib/policy-definition.d.ts +260 -0
- package/lib/azure-policydefinition/lib/policy-definition.js +199 -0
- package/lib/azure-policydefinition/test/policy-definition.integ.d.ts +9 -0
- package/lib/azure-policydefinition/test/policy-definition.integ.js +137 -0
- package/lib/azure-policydefinition/test/policy-definition.spec.d.ts +9 -0
- package/lib/azure-policydefinition/test/policy-definition.spec.js +596 -0
- package/lib/azure-privatednszone/index.d.ts +1 -0
- package/lib/azure-privatednszone/index.js +18 -0
- package/lib/azure-privatednszone/lib/index.d.ts +2 -0
- package/lib/azure-privatednszone/lib/index.js +19 -0
- package/lib/azure-privatednszone/lib/private-dns-zone-schemas.d.ts +24 -0
- package/lib/azure-privatednszone/lib/private-dns-zone-schemas.js +254 -0
- package/lib/azure-privatednszone/lib/private-dns-zone.d.ts +178 -0
- package/lib/azure-privatednszone/lib/private-dns-zone.js +272 -0
- package/lib/azure-privatednszone/test/private-dns-zone.integ.d.ts +9 -0
- package/lib/azure-privatednszone/test/private-dns-zone.integ.js +84 -0
- package/lib/azure-privatednszone/test/private-dns-zone.spec.d.ts +9 -0
- package/lib/azure-privatednszone/test/private-dns-zone.spec.js +341 -0
- package/lib/azure-privatednszonelink/index.d.ts +1 -0
- package/lib/azure-privatednszonelink/index.js +18 -0
- package/lib/azure-privatednszonelink/lib/index.d.ts +2 -0
- package/lib/azure-privatednszonelink/lib/index.js +19 -0
- package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.d.ts +24 -0
- package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.js +262 -0
- package/lib/azure-privatednszonelink/lib/private-dns-zone-link.d.ts +202 -0
- package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +250 -0
- package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.d.ts +9 -0
- package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.js +110 -0
- package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.d.ts +9 -0
- package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.js +465 -0
- package/lib/azure-publicipaddress/index.d.ts +0 -5
- package/lib/azure-publicipaddress/index.js +1 -6
- package/lib/azure-publicipaddress/lib/index.d.ts +2 -9
- package/lib/azure-publicipaddress/lib/index.js +17 -17
- package/lib/azure-publicipaddress/lib/public-ip-address.d.ts +4 -13
- package/lib/azure-publicipaddress/lib/public-ip-address.js +14 -36
- package/lib/azure-resourcegroup/index.d.ts +0 -37
- package/lib/azure-resourcegroup/index.js +1 -39
- package/lib/azure-resourcegroup/lib/index.d.ts +1 -44
- package/lib/azure-resourcegroup/lib/index.js +2 -43
- package/lib/azure-resourcegroup/lib/resource-group.d.ts +9 -23
- package/lib/azure-resourcegroup/lib/resource-group.js +23 -56
- package/lib/azure-resourcegroup/test/resource-group.spec.js +13 -19
- package/lib/azure-roleassignment/index.d.ts +1 -0
- package/lib/azure-roleassignment/index.js +18 -0
- package/lib/azure-roleassignment/lib/index.d.ts +2 -0
- package/lib/azure-roleassignment/lib/index.js +19 -0
- package/lib/azure-roleassignment/lib/role-assignment-schemas.d.ts +25 -0
- package/lib/azure-roleassignment/lib/role-assignment-schemas.js +238 -0
- package/lib/azure-roleassignment/lib/role-assignment.d.ts +294 -0
- package/lib/azure-roleassignment/lib/role-assignment.js +257 -0
- package/lib/azure-roleassignment/test/role-assignment.integ.d.ts +12 -0
- package/lib/azure-roleassignment/test/role-assignment.integ.js +101 -0
- package/lib/azure-roleassignment/test/role-assignment.spec.d.ts +9 -0
- package/lib/azure-roleassignment/test/role-assignment.spec.js +633 -0
- package/lib/azure-roledefinition/index.d.ts +1 -0
- package/lib/azure-roledefinition/index.js +18 -0
- package/lib/azure-roledefinition/lib/index.d.ts +2 -0
- package/lib/azure-roledefinition/lib/index.js +19 -0
- package/lib/azure-roledefinition/lib/role-definition-schemas.d.ts +25 -0
- package/lib/azure-roledefinition/lib/role-definition-schemas.js +195 -0
- package/lib/azure-roledefinition/lib/role-definition.d.ts +236 -0
- package/lib/azure-roledefinition/lib/role-definition.js +192 -0
- package/lib/azure-roledefinition/test/role-definition.integ.d.ts +12 -0
- package/lib/azure-roledefinition/test/role-definition.integ.js +142 -0
- package/lib/azure-roledefinition/test/role-definition.spec.d.ts +9 -0
- package/lib/azure-roledefinition/test/role-definition.spec.js +946 -0
- package/lib/azure-storageaccount/index.d.ts +0 -19
- package/lib/azure-storageaccount/index.js +1 -20
- package/lib/azure-storageaccount/lib/index.d.ts +1 -7
- package/lib/azure-storageaccount/lib/index.js +2 -8
- package/lib/azure-storageaccount/lib/storage-account.d.ts +4 -9
- package/lib/azure-storageaccount/lib/storage-account.js +15 -29
- package/lib/azure-subnet/index.d.ts +0 -3
- package/lib/azure-subnet/index.js +1 -4
- package/lib/azure-subnet/lib/index.d.ts +1 -4
- package/lib/azure-subnet/lib/index.js +2 -5
- package/lib/azure-subnet/lib/subnet.d.ts +3 -14
- package/lib/azure-subnet/lib/subnet.js +28 -47
- package/lib/azure-subnet/test/subnet.integ.js +19 -7
- package/lib/azure-subnet/test/subnet.spec.js +1 -2
- package/lib/azure-virtualmachine/index.d.ts +0 -6
- package/lib/azure-virtualmachine/index.js +1 -7
- package/lib/azure-virtualmachine/lib/index.d.ts +1 -10
- package/lib/azure-virtualmachine/lib/index.js +2 -21
- package/lib/azure-virtualmachine/lib/virtual-machine.d.ts +4 -13
- package/lib/azure-virtualmachine/lib/virtual-machine.js +15 -36
- package/lib/azure-virtualnetwork/index.d.ts +0 -9
- package/lib/azure-virtualnetwork/index.js +1 -11
- package/lib/azure-virtualnetwork/lib/index.d.ts +2 -9
- package/lib/azure-virtualnetwork/lib/index.js +17 -20
- package/lib/azure-virtualnetwork/lib/virtual-network.d.ts +4 -13
- package/lib/azure-virtualnetwork/lib/virtual-network.js +15 -36
- package/lib/azure-virtualnetworkmanager/index.d.ts +1 -0
- package/lib/azure-virtualnetworkmanager/index.js +18 -0
- package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.d.ts +48 -0
- package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.js +265 -0
- package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.d.ts +185 -0
- package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +206 -0
- package/lib/azure-virtualnetworkmanager/lib/index.d.ts +14 -0
- package/lib/azure-virtualnetworkmanager/lib/index.js +31 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.d.ts +32 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.js +189 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.d.ts +32 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.js +201 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.d.ts +135 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +163 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group.d.ts +139 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group.js +158 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.d.ts +32 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.js +182 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.d.ts +144 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +164 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.d.ts +38 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.js +206 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.d.ts +142 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +162 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.d.ts +39 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.js +359 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.d.ts +221 -0
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +204 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.d.ts +32 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.js +236 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.d.ts +337 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +283 -0
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.d.ts +25 -0
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.js +402 -0
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.d.ts +9 -0
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.js +1652 -0
- package/lib/azure-vmss/index.d.ts +0 -5
- package/lib/azure-vmss/index.js +1 -6
- package/lib/azure-vmss/lib/index.d.ts +0 -7
- package/lib/azure-vmss/lib/index.js +1 -21
- package/lib/azure-vmss/lib/virtual-machine-scale-set.d.ts +5 -13
- package/lib/azure-vmss/lib/virtual-machine-scale-set.js +29 -53
- package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.d.ts +10 -0
- package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.js +218 -0
- package/lib/core-azure/lib/azapi/azapi-resource.d.ts +178 -26
- package/lib/core-azure/lib/azapi/azapi-resource.js +328 -90
- package/lib/core-azure/lib/azapi/azapi-resource.spec.js +2 -2
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
- package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +5 -3
- package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
- package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
- package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
- package/lib/core-azure/lib/azapi/resource-schema-validator.d.ts +118 -0
- package/lib/core-azure/lib/azapi/resource-schema-validator.js +236 -0
- package/lib/core-azure/lib/azapi/resource-version-manager.d.ts +103 -0
- package/lib/core-azure/lib/azapi/resource-version-manager.js +168 -0
- package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +11 -6
- package/lib/core-azure/lib/index.d.ts +2 -2
- package/lib/core-azure/lib/index.js +5 -5
- package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
- package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
- package/lib/index.d.ts +19 -0
- package/lib/index.js +21 -2
- package/lib/testing/index.js +2 -2
- package/lib/testing/lib/cleanup.d.ts +1 -0
- package/lib/testing/lib/cleanup.js +19 -12
- package/lib/testing/lib/metadata.js +19 -16
- package/package.json +1 -1
- package/scripts/cleanup-test-resources.ts +22 -4
- package/scripts/generate-index.js +25 -8
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Comprehensive tests for the unified PolicyDefinition implementation
|
|
4
|
+
*
|
|
5
|
+
* This test suite validates the unified PolicyDefinition class that uses
|
|
6
|
+
* the VersionedAzapiResource framework. Tests cover automatic version resolution,
|
|
7
|
+
* explicit version pinning, schema validation, property transformation, and
|
|
8
|
+
* policy-specific functionality.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const cdktf_1 = require("cdktf");
|
|
12
|
+
const cdktf = require("cdktf");
|
|
13
|
+
const api_version_manager_1 = require("../../core-azure/lib/version-manager/api-version-manager");
|
|
14
|
+
const version_interfaces_1 = require("../../core-azure/lib/version-manager/interfaces/version-interfaces");
|
|
15
|
+
const policy_definition_1 = require("../lib/policy-definition");
|
|
16
|
+
const policy_definition_schemas_1 = require("../lib/policy-definition-schemas");
|
|
17
|
+
describe("PolicyDefinition - Unified Implementation", () => {
|
|
18
|
+
let app;
|
|
19
|
+
let stack;
|
|
20
|
+
let manager;
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
app = cdktf_1.Testing.app();
|
|
23
|
+
stack = new cdktf.TerraformStack(app, "TestStack");
|
|
24
|
+
manager = api_version_manager_1.ApiVersionManager.instance();
|
|
25
|
+
// Ensure Policy Definition schemas are registered
|
|
26
|
+
try {
|
|
27
|
+
manager.registerResourceType(policy_definition_schemas_1.POLICY_DEFINITION_TYPE, policy_definition_schemas_1.ALL_POLICY_DEFINITION_VERSIONS);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// Ignore if already registered
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
describe("Constructor and Basic Properties", () => {
|
|
34
|
+
it("should create policy definition with automatic latest version resolution", () => {
|
|
35
|
+
const props = {
|
|
36
|
+
name: "test-policy",
|
|
37
|
+
policyRule: {
|
|
38
|
+
if: {
|
|
39
|
+
field: "tags['Environment']",
|
|
40
|
+
exists: "false",
|
|
41
|
+
},
|
|
42
|
+
then: {
|
|
43
|
+
effect: "deny",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
48
|
+
expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
|
|
49
|
+
expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01"); // Latest version
|
|
50
|
+
expect(policyDefinition.props).toBe(props);
|
|
51
|
+
expect(policyDefinition.name).toBe("test-policy");
|
|
52
|
+
});
|
|
53
|
+
it("should create policy definition with explicit version pinning", () => {
|
|
54
|
+
const props = {
|
|
55
|
+
name: "test-policy-pinned",
|
|
56
|
+
apiVersion: "2021-06-01",
|
|
57
|
+
policyRule: {
|
|
58
|
+
if: {
|
|
59
|
+
field: "type",
|
|
60
|
+
equals: "Microsoft.Compute/virtualMachines",
|
|
61
|
+
},
|
|
62
|
+
then: {
|
|
63
|
+
effect: "audit",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
68
|
+
expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01");
|
|
69
|
+
});
|
|
70
|
+
it("should create policy definition with all optional properties", () => {
|
|
71
|
+
const props = {
|
|
72
|
+
name: "test-policy-full",
|
|
73
|
+
displayName: "Test Policy Definition",
|
|
74
|
+
description: "A test policy definition for unit testing",
|
|
75
|
+
policyType: "Custom",
|
|
76
|
+
mode: "All",
|
|
77
|
+
policyRule: {
|
|
78
|
+
if: {
|
|
79
|
+
field: "location",
|
|
80
|
+
notIn: ["eastus", "westus"],
|
|
81
|
+
},
|
|
82
|
+
then: {
|
|
83
|
+
effect: "deny",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
parameters: {
|
|
87
|
+
allowedLocations: {
|
|
88
|
+
type: "Array",
|
|
89
|
+
metadata: {
|
|
90
|
+
displayName: "Allowed locations",
|
|
91
|
+
description: "The list of allowed locations for resources",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
metadata: {
|
|
96
|
+
category: "General",
|
|
97
|
+
version: "1.0.0",
|
|
98
|
+
},
|
|
99
|
+
ignoreChanges: ["metadata"],
|
|
100
|
+
enableValidation: true,
|
|
101
|
+
enableMigrationAnalysis: true,
|
|
102
|
+
enableTransformation: true,
|
|
103
|
+
};
|
|
104
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
105
|
+
expect(policyDefinition.props.displayName).toBe("Test Policy Definition");
|
|
106
|
+
expect(policyDefinition.props.description).toBe("A test policy definition for unit testing");
|
|
107
|
+
expect(policyDefinition.props.policyType).toBe("Custom");
|
|
108
|
+
expect(policyDefinition.props.mode).toBe("All");
|
|
109
|
+
expect(policyDefinition.props.parameters).toBeDefined();
|
|
110
|
+
expect(policyDefinition.props.metadata).toBeDefined();
|
|
111
|
+
});
|
|
112
|
+
it("should use default name when name is not provided", () => {
|
|
113
|
+
const props = {
|
|
114
|
+
policyRule: {
|
|
115
|
+
if: {
|
|
116
|
+
field: "type",
|
|
117
|
+
equals: "Microsoft.Storage/storageAccounts",
|
|
118
|
+
},
|
|
119
|
+
then: {
|
|
120
|
+
effect: "audit",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
125
|
+
expect(policyDefinition.name).toBe("TestPolicyDefinition");
|
|
126
|
+
});
|
|
127
|
+
it("should require policyRule to be provided", () => {
|
|
128
|
+
const props = {
|
|
129
|
+
name: "test-policy",
|
|
130
|
+
};
|
|
131
|
+
expect(() => {
|
|
132
|
+
new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
133
|
+
}).toThrow("Required property 'policyRule' is missing");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("Framework Integration", () => {
|
|
137
|
+
it("should resolve latest API version automatically", () => {
|
|
138
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
139
|
+
name: "test-policy",
|
|
140
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
141
|
+
});
|
|
142
|
+
expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01");
|
|
143
|
+
expect(policyDefinition.latestVersion()).toBe("2021-06-01");
|
|
144
|
+
});
|
|
145
|
+
it("should support all registered API versions", () => {
|
|
146
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
147
|
+
name: "test-policy",
|
|
148
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
149
|
+
});
|
|
150
|
+
const supportedVersions = policyDefinition.supportedVersions();
|
|
151
|
+
expect(supportedVersions).toContain("2021-06-01");
|
|
152
|
+
});
|
|
153
|
+
it("should validate version support", () => {
|
|
154
|
+
// Valid version
|
|
155
|
+
expect(() => {
|
|
156
|
+
new policy_definition_1.PolicyDefinition(stack, "ValidVersion", {
|
|
157
|
+
name: "test-policy",
|
|
158
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
159
|
+
apiVersion: "2021-06-01",
|
|
160
|
+
});
|
|
161
|
+
}).not.toThrow();
|
|
162
|
+
// Invalid version
|
|
163
|
+
expect(() => {
|
|
164
|
+
new policy_definition_1.PolicyDefinition(stack, "InvalidVersion", {
|
|
165
|
+
name: "test-policy",
|
|
166
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
167
|
+
apiVersion: "2022-01-01",
|
|
168
|
+
});
|
|
169
|
+
}).toThrow("Unsupported API version '2022-01-01'");
|
|
170
|
+
});
|
|
171
|
+
it("should load correct schema for resolved version", () => {
|
|
172
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
173
|
+
name: "test-policy",
|
|
174
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
175
|
+
apiVersion: "2021-06-01",
|
|
176
|
+
});
|
|
177
|
+
expect(policyDefinition.schema).toBeDefined();
|
|
178
|
+
expect(policyDefinition.schema.resourceType).toBe(policy_definition_schemas_1.POLICY_DEFINITION_TYPE);
|
|
179
|
+
expect(policyDefinition.schema.version).toBe("2021-06-01");
|
|
180
|
+
expect(policyDefinition.schema.properties).toBeDefined();
|
|
181
|
+
});
|
|
182
|
+
it("should load version configuration correctly", () => {
|
|
183
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
184
|
+
name: "test-policy",
|
|
185
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
186
|
+
});
|
|
187
|
+
expect(policyDefinition.versionConfig).toBeDefined();
|
|
188
|
+
expect(policyDefinition.versionConfig.version).toBe("2021-06-01");
|
|
189
|
+
expect(policyDefinition.versionConfig.supportLevel).toBe(version_interfaces_1.VersionSupportLevel.ACTIVE);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe("Property Validation", () => {
|
|
193
|
+
it("should validate properties when validation is enabled", () => {
|
|
194
|
+
const props = {
|
|
195
|
+
name: "test-policy",
|
|
196
|
+
policyRule: {
|
|
197
|
+
if: {
|
|
198
|
+
field: "type",
|
|
199
|
+
equals: "Microsoft.Compute/virtualMachines",
|
|
200
|
+
},
|
|
201
|
+
then: {
|
|
202
|
+
effect: "audit",
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
enableValidation: true,
|
|
206
|
+
};
|
|
207
|
+
expect(() => {
|
|
208
|
+
new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
|
|
209
|
+
}).not.toThrow();
|
|
210
|
+
});
|
|
211
|
+
it("should have validation results for valid properties", () => {
|
|
212
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
213
|
+
name: "valid-policy",
|
|
214
|
+
displayName: "Valid Policy",
|
|
215
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
216
|
+
enableValidation: true,
|
|
217
|
+
});
|
|
218
|
+
expect(policyDefinition.validationResult).toBeDefined();
|
|
219
|
+
expect(policyDefinition.validationResult.valid).toBe(true);
|
|
220
|
+
expect(policyDefinition.validationResult.errors).toHaveLength(0);
|
|
221
|
+
});
|
|
222
|
+
it("should skip validation when disabled", () => {
|
|
223
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
224
|
+
name: "test-policy",
|
|
225
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
226
|
+
enableValidation: false,
|
|
227
|
+
});
|
|
228
|
+
expect(policyDefinition).toBeDefined();
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
describe("Migration Analysis", () => {
|
|
232
|
+
it("should skip migration analysis for single version", () => {
|
|
233
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
234
|
+
name: "test-policy",
|
|
235
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
236
|
+
apiVersion: "2021-06-01",
|
|
237
|
+
});
|
|
238
|
+
// Since there's only one version, migration analysis should be skipped
|
|
239
|
+
expect(policyDefinition).toBeDefined();
|
|
240
|
+
});
|
|
241
|
+
it("should skip migration analysis when disabled", () => {
|
|
242
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
243
|
+
name: "test-policy",
|
|
244
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
245
|
+
enableMigrationAnalysis: false,
|
|
246
|
+
});
|
|
247
|
+
expect(policyDefinition.migrationAnalysis).toBeUndefined();
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
describe("Resource Creation and Body", () => {
|
|
251
|
+
it("should create correct resource body with minimal properties", () => {
|
|
252
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
253
|
+
name: "test-policy",
|
|
254
|
+
policyRule: {
|
|
255
|
+
if: {
|
|
256
|
+
field: "tags['Environment']",
|
|
257
|
+
exists: "false",
|
|
258
|
+
},
|
|
259
|
+
then: {
|
|
260
|
+
effect: "deny",
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
expect(policyDefinition).toBeDefined();
|
|
265
|
+
expect(policyDefinition.props.policyRule).toBeDefined();
|
|
266
|
+
});
|
|
267
|
+
it("should create correct resource body with all properties", () => {
|
|
268
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
269
|
+
name: "test-policy",
|
|
270
|
+
displayName: "Test Policy",
|
|
271
|
+
description: "A test policy",
|
|
272
|
+
policyType: "Custom",
|
|
273
|
+
mode: "Indexed",
|
|
274
|
+
policyRule: {
|
|
275
|
+
if: {
|
|
276
|
+
field: "location",
|
|
277
|
+
notIn: ["eastus", "westus"],
|
|
278
|
+
},
|
|
279
|
+
then: {
|
|
280
|
+
effect: "deny",
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
parameters: {
|
|
284
|
+
allowedLocations: {
|
|
285
|
+
type: "Array",
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
metadata: {
|
|
289
|
+
category: "Compliance",
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
expect(policyDefinition).toBeDefined();
|
|
293
|
+
expect(policyDefinition.props.displayName).toBe("Test Policy");
|
|
294
|
+
expect(policyDefinition.props.policyType).toBe("Custom");
|
|
295
|
+
expect(policyDefinition.props.mode).toBe("Indexed");
|
|
296
|
+
});
|
|
297
|
+
it("should create Terraform outputs", () => {
|
|
298
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
299
|
+
name: "test-policy-outputs",
|
|
300
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
301
|
+
});
|
|
302
|
+
expect(policyDefinition.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
303
|
+
expect(policyDefinition.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
describe("Public Methods and Properties", () => {
|
|
307
|
+
let policyDefinition;
|
|
308
|
+
beforeEach(() => {
|
|
309
|
+
policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
|
|
310
|
+
name: "test-policy",
|
|
311
|
+
displayName: "Test Policy",
|
|
312
|
+
policyType: "Custom",
|
|
313
|
+
mode: "All",
|
|
314
|
+
policyRule: {
|
|
315
|
+
if: {
|
|
316
|
+
field: "type",
|
|
317
|
+
equals: "Microsoft.Compute/virtualMachines",
|
|
318
|
+
},
|
|
319
|
+
then: {
|
|
320
|
+
effect: "audit",
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
it("should have correct id format", () => {
|
|
326
|
+
expect(policyDefinition.id).toMatch(/^\$\{.*\.id\}$/);
|
|
327
|
+
});
|
|
328
|
+
it("should have resourceId property matching id", () => {
|
|
329
|
+
expect(policyDefinition.resourceId).toBe(policyDefinition.id);
|
|
330
|
+
});
|
|
331
|
+
it("should return correct policyType", () => {
|
|
332
|
+
expect(policyDefinition.policyType).toBe("Custom");
|
|
333
|
+
});
|
|
334
|
+
it("should return correct policyMode", () => {
|
|
335
|
+
expect(policyDefinition.policyMode).toBe("All");
|
|
336
|
+
});
|
|
337
|
+
it("should use default policyType when not provided", () => {
|
|
338
|
+
const defaultPolicy = new policy_definition_1.PolicyDefinition(stack, "DefaultTypePolicy", {
|
|
339
|
+
name: "default-policy",
|
|
340
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
341
|
+
});
|
|
342
|
+
expect(defaultPolicy.policyType).toBe("Custom");
|
|
343
|
+
});
|
|
344
|
+
it("should use default mode when not provided", () => {
|
|
345
|
+
const defaultPolicy = new policy_definition_1.PolicyDefinition(stack, "DefaultModePolicy", {
|
|
346
|
+
name: "default-policy",
|
|
347
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
348
|
+
});
|
|
349
|
+
expect(defaultPolicy.policyMode).toBe("All");
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
describe("Ignore Changes Configuration", () => {
|
|
353
|
+
it("should apply ignore changes lifecycle rules", () => {
|
|
354
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "IgnoreChangesPolicy", {
|
|
355
|
+
name: "test-policy",
|
|
356
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
357
|
+
ignoreChanges: ["metadata", "description"],
|
|
358
|
+
});
|
|
359
|
+
expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
|
|
360
|
+
});
|
|
361
|
+
it("should handle empty ignore changes array", () => {
|
|
362
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "EmptyIgnorePolicy", {
|
|
363
|
+
name: "test-policy",
|
|
364
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
365
|
+
ignoreChanges: [],
|
|
366
|
+
});
|
|
367
|
+
expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
describe("Policy Rule Validation", () => {
|
|
371
|
+
it("should accept complex policy rules", () => {
|
|
372
|
+
const complexRule = {
|
|
373
|
+
if: {
|
|
374
|
+
allOf: [
|
|
375
|
+
{
|
|
376
|
+
field: "type",
|
|
377
|
+
equals: "Microsoft.Storage/storageAccounts",
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
field: "Microsoft.Storage/storageAccounts/enableHttpsTrafficOnly",
|
|
381
|
+
notEquals: "true",
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
},
|
|
385
|
+
then: {
|
|
386
|
+
effect: "deny",
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "ComplexRulePolicy", {
|
|
390
|
+
name: "complex-policy",
|
|
391
|
+
policyRule: complexRule,
|
|
392
|
+
});
|
|
393
|
+
expect(policyDefinition).toBeDefined();
|
|
394
|
+
expect(policyDefinition.props.policyRule).toEqual(complexRule);
|
|
395
|
+
});
|
|
396
|
+
it("should accept policy rules with parameters", () => {
|
|
397
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "ParameterizedPolicy", {
|
|
398
|
+
name: "parameterized-policy",
|
|
399
|
+
policyRule: {
|
|
400
|
+
if: {
|
|
401
|
+
field: "[concat('tags[', parameters('tagName'), ']')]",
|
|
402
|
+
exists: "false",
|
|
403
|
+
},
|
|
404
|
+
then: {
|
|
405
|
+
effect: "[parameters('effect')]",
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
parameters: {
|
|
409
|
+
tagName: {
|
|
410
|
+
type: "String",
|
|
411
|
+
metadata: {
|
|
412
|
+
displayName: "Tag Name",
|
|
413
|
+
description: "Name of the tag to check",
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
effect: {
|
|
417
|
+
type: "String",
|
|
418
|
+
allowedValues: ["audit", "deny"],
|
|
419
|
+
defaultValue: "audit",
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
expect(policyDefinition).toBeDefined();
|
|
424
|
+
expect(policyDefinition.props.parameters).toBeDefined();
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
describe("Error Handling", () => {
|
|
428
|
+
it("should handle invalid API versions gracefully", () => {
|
|
429
|
+
expect(() => {
|
|
430
|
+
new policy_definition_1.PolicyDefinition(stack, "InvalidAPI", {
|
|
431
|
+
name: "test-policy",
|
|
432
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
433
|
+
apiVersion: "invalid-version",
|
|
434
|
+
});
|
|
435
|
+
}).toThrow("Unsupported API version 'invalid-version'");
|
|
436
|
+
});
|
|
437
|
+
it("should handle validation errors when validation is enabled", () => {
|
|
438
|
+
expect(() => {
|
|
439
|
+
new policy_definition_1.PolicyDefinition(stack, "ValidationError", {
|
|
440
|
+
name: "test-policy",
|
|
441
|
+
policyRule: undefined, // Missing required policyRule
|
|
442
|
+
enableValidation: true,
|
|
443
|
+
});
|
|
444
|
+
}).toThrow("Required property 'policyRule' is missing");
|
|
445
|
+
});
|
|
446
|
+
it("should handle schema registration errors gracefully", () => {
|
|
447
|
+
expect(() => {
|
|
448
|
+
new policy_definition_1.PolicyDefinition(stack, "SchemaTest", {
|
|
449
|
+
name: "test-policy",
|
|
450
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
451
|
+
});
|
|
452
|
+
}).not.toThrow();
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
describe("JSII Compliance", () => {
|
|
456
|
+
it("should have JSII-compliant constructor", () => {
|
|
457
|
+
expect(() => {
|
|
458
|
+
new policy_definition_1.PolicyDefinition(stack, "JsiiTest", {
|
|
459
|
+
name: "jsii-test",
|
|
460
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
461
|
+
});
|
|
462
|
+
}).not.toThrow();
|
|
463
|
+
});
|
|
464
|
+
it("should have JSII-compliant properties", () => {
|
|
465
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiProps", {
|
|
466
|
+
name: "jsii-props",
|
|
467
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
468
|
+
});
|
|
469
|
+
expect(typeof policyDefinition.id).toBe("string");
|
|
470
|
+
expect(typeof policyDefinition.name).toBe("string");
|
|
471
|
+
expect(typeof policyDefinition.resolvedApiVersion).toBe("string");
|
|
472
|
+
expect(typeof policyDefinition.policyType).toBe("string");
|
|
473
|
+
expect(typeof policyDefinition.policyMode).toBe("string");
|
|
474
|
+
});
|
|
475
|
+
it("should have JSII-compliant methods", () => {
|
|
476
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiMethods", {
|
|
477
|
+
name: "jsii-methods",
|
|
478
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
479
|
+
});
|
|
480
|
+
expect(typeof policyDefinition.latestVersion).toBe("function");
|
|
481
|
+
expect(typeof policyDefinition.supportedVersions).toBe("function");
|
|
482
|
+
});
|
|
483
|
+
it("should serialize complex objects correctly", () => {
|
|
484
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiSerialization", {
|
|
485
|
+
name: "jsii-serialization",
|
|
486
|
+
policyRule: {
|
|
487
|
+
if: { field: "location", equals: "eastus" },
|
|
488
|
+
then: { effect: "deny" },
|
|
489
|
+
},
|
|
490
|
+
parameters: {
|
|
491
|
+
testParam: {
|
|
492
|
+
type: "String",
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
expect(() => JSON.stringify(policyDefinition.validationResult)).not.toThrow();
|
|
497
|
+
expect(() => JSON.stringify(policyDefinition.schema)).not.toThrow();
|
|
498
|
+
expect(() => JSON.stringify(policyDefinition.versionConfig)).not.toThrow();
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
describe("CDK Terraform Integration", () => {
|
|
502
|
+
it("should synthesize to valid Terraform configuration", () => {
|
|
503
|
+
new policy_definition_1.PolicyDefinition(stack, "SynthTest", {
|
|
504
|
+
name: "synth-test",
|
|
505
|
+
policyRule: {
|
|
506
|
+
if: {
|
|
507
|
+
field: "type",
|
|
508
|
+
equals: "Microsoft.Compute/virtualMachines",
|
|
509
|
+
},
|
|
510
|
+
then: {
|
|
511
|
+
effect: "audit",
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
});
|
|
515
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
516
|
+
expect(synthesized).toBeDefined();
|
|
517
|
+
const stackConfig = JSON.parse(synthesized);
|
|
518
|
+
expect(stackConfig.resource).toBeDefined();
|
|
519
|
+
});
|
|
520
|
+
it("should work in complex CDK constructs", () => {
|
|
521
|
+
class ComplexConstruct extends cdktf.TerraformStack {
|
|
522
|
+
constructor(scope, id) {
|
|
523
|
+
super(scope, id);
|
|
524
|
+
const policy1 = new policy_definition_1.PolicyDefinition(this, "Policy1", {
|
|
525
|
+
name: "policy-1",
|
|
526
|
+
displayName: "First Policy",
|
|
527
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
528
|
+
});
|
|
529
|
+
const policy2 = new policy_definition_1.PolicyDefinition(this, "Policy2", {
|
|
530
|
+
name: "policy-2",
|
|
531
|
+
displayName: "Second Policy",
|
|
532
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
533
|
+
apiVersion: "2021-06-01",
|
|
534
|
+
});
|
|
535
|
+
new cdktf.TerraformOutput(this, "Policy1Id", {
|
|
536
|
+
value: policy1.id,
|
|
537
|
+
});
|
|
538
|
+
new cdktf.TerraformOutput(this, "Policy2Id", {
|
|
539
|
+
value: policy2.id,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
expect(() => {
|
|
544
|
+
new ComplexConstruct(app, "ComplexStack");
|
|
545
|
+
}).not.toThrow();
|
|
546
|
+
});
|
|
547
|
+
it("should handle multiple policy definitions in the same stack", () => {
|
|
548
|
+
const policy1 = new policy_definition_1.PolicyDefinition(stack, "PolicyDefinition1", {
|
|
549
|
+
name: "policy-1",
|
|
550
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
551
|
+
});
|
|
552
|
+
const policy2 = new policy_definition_1.PolicyDefinition(stack, "PolicyDefinition2", {
|
|
553
|
+
name: "policy-2",
|
|
554
|
+
policyRule: { if: {}, then: { effect: "deny" } },
|
|
555
|
+
apiVersion: "2021-06-01",
|
|
556
|
+
});
|
|
557
|
+
expect(policy1.resolvedApiVersion).toBe("2021-06-01");
|
|
558
|
+
expect(policy2.resolvedApiVersion).toBe("2021-06-01");
|
|
559
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
560
|
+
expect(synthesized).toBeDefined();
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
describe("Policy Definition Types", () => {
|
|
564
|
+
it("should support BuiltIn policy type", () => {
|
|
565
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "BuiltInPolicy", {
|
|
566
|
+
name: "builtin-policy",
|
|
567
|
+
policyType: "BuiltIn",
|
|
568
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
569
|
+
});
|
|
570
|
+
expect(policyDefinition.policyType).toBe("BuiltIn");
|
|
571
|
+
});
|
|
572
|
+
it("should support Static policy type", () => {
|
|
573
|
+
const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "StaticPolicy", {
|
|
574
|
+
name: "static-policy",
|
|
575
|
+
policyType: "Static",
|
|
576
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
577
|
+
});
|
|
578
|
+
expect(policyDefinition.policyType).toBe("Static");
|
|
579
|
+
});
|
|
580
|
+
it("should support different policy modes", () => {
|
|
581
|
+
const indexedPolicy = new policy_definition_1.PolicyDefinition(stack, "IndexedPolicy", {
|
|
582
|
+
name: "indexed-policy",
|
|
583
|
+
mode: "Indexed",
|
|
584
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
585
|
+
});
|
|
586
|
+
expect(indexedPolicy.policyMode).toBe("Indexed");
|
|
587
|
+
const resourceProviderPolicy = new policy_definition_1.PolicyDefinition(stack, "ResourceProviderPolicy", {
|
|
588
|
+
name: "resource-provider-policy",
|
|
589
|
+
mode: "Microsoft.KeyVault.Data",
|
|
590
|
+
policyRule: { if: {}, then: { effect: "audit" } },
|
|
591
|
+
});
|
|
592
|
+
expect(resourceProviderPolicy.policyMode).toBe("Microsoft.KeyVault.Data");
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LWRlZmluaXRpb24uc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9henVyZS1wb2xpY3lkZWZpbml0aW9uL3Rlc3QvcG9saWN5LWRlZmluaXRpb24uc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7QUFFSCxpQ0FBZ0M7QUFDaEMsK0JBQStCO0FBQy9CLGtHQUE2RjtBQUM3RiwyR0FBeUc7QUFDekcsZ0VBR2tDO0FBQ2xDLGdGQUcwQztBQUUxQyxRQUFRLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO0lBQ3pELElBQUksR0FBYyxDQUFDO0lBQ25CLElBQUksS0FBMkIsQ0FBQztJQUNoQyxJQUFJLE9BQTBCLENBQUM7SUFFL0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxlQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDcEIsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDbkQsT0FBTyxHQUFHLHVDQUFpQixDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXZDLGtEQUFrRDtRQUNsRCxJQUFJLENBQUM7WUFDSCxPQUFPLENBQUMsb0JBQW9CLENBQzFCLGtEQUFzQixFQUN0QiwwREFBOEIsQ0FDL0IsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsK0JBQStCO1FBQ2pDLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsRUFBRSxDQUFDLDBFQUEwRSxFQUFFLEdBQUcsRUFBRTtZQUNsRixNQUFNLEtBQUssR0FBMEI7Z0JBQ25DLElBQUksRUFBRSxhQUFhO2dCQUNuQixVQUFVLEVBQUU7b0JBQ1YsRUFBRSxFQUFFO3dCQUNGLEtBQUssRUFBRSxxQkFBcUI7d0JBQzVCLE1BQU0sRUFBRSxP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Q0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7WUFDL0MsTUFBTSxhQUFhLEdBQUcsSUFBSSxvQ0FBZ0IsQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFO2dCQUNqRSxJQUFJLEVBQUUsZ0JBQWdCO2dCQUN0QixJQUFJLEVBQUUsU0FBUztnQkFDZixVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRTthQUNsRCxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVqRCxNQUFNLHNCQUFzQixHQUFHLElBQUksb0NBQWdCLENBQ2pELEtBQUssRUFDTCx3QkFBd0IsRUFDeEI7Z0JBQ0UsSUFBSSxFQUFFLDBCQUEwQjtnQkFDaEMsSUFBSSxFQUFFLHlCQUF5QjtnQkFDL0IsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUU7YUFDbEQsQ0FDRixDQUFDO1lBRUYsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tcHJlaGVuc2l2ZSB0ZXN0cyBmb3IgdGhlIHVuaWZpZWQgUG9saWN5RGVmaW5pdGlvbiBpbXBsZW1lbnRhdGlvblxuICpcbiAqIFRoaXMgdGVzdCBzdWl0ZSB2YWxpZGF0ZXMgdGhlIHVuaWZpZWQgUG9saWN5RGVmaW5pdGlvbiBjbGFzcyB0aGF0IHVzZXNcbiAqIHRoZSBWZXJzaW9uZWRBemFwaVJlc291cmNlIGZyYW1ld29yay4gVGVzdHMgY292ZXIgYXV0b21hdGljIHZlcnNpb24gcmVzb2x1dGlvbixcbiAqIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZywgc2NoZW1hIHZhbGlkYXRpb24sIHByb3BlcnR5IHRyYW5zZm9ybWF0aW9uLCBhbmRcbiAqIHBvbGljeS1zcGVjaWZpYyBmdW5jdGlvbmFsaXR5LlxuICovXG5cbmltcG9ydCB7IFRlc3RpbmcgfSBmcm9tIFwiY2RrdGZcIjtcbmltcG9ydCAqIGFzIGNka3RmIGZyb20gXCJjZGt0ZlwiO1xuaW1wb3J0IHsgQXBpVmVyc2lvbk1hbmFnZXIgfSBmcm9tIFwiLi4vLi4vY29yZS1henVyZS9saWIvdmVyc2lvbi1tYW5hZ2VyL2FwaS12ZXJzaW9uLW1hbmFnZXJcIjtcbmltcG9ydCB7IFZlcnNpb25TdXBwb3J0TGV2ZWwgfSBmcm9tIFwiLi4vLi4vY29yZS1henVyZS9saWIvdmVyc2lvbi1tYW5hZ2VyL2ludGVyZmFjZXMvdmVyc2lvbi1pbnRlcmZhY2VzXCI7XG5pbXBvcnQge1xuICBQb2xpY3lEZWZpbml0aW9uLFxuICBQb2xpY3lEZWZpbml0aW9uUHJvcHMsXG59IGZyb20gXCIuLi9saWIvcG9saWN5LWRlZmluaXRpb25cIjtcbmltcG9ydCB7XG4gIEFMTF9QT0xJQ1lfREVGSU5JVElPTl9WRVJTSU9OUyxcbiAgUE9MSUNZX0RFRklOSVRJT05fVFlQRSxcbn0gZnJvbSBcIi4uL2xpYi9wb2xpY3ktZGVmaW5pdGlvbi1zY2hlbWFzXCI7XG5cbmRlc2NyaWJlKFwiUG9saWN5RGVmaW5pdGlvbiAtIFVuaWZpZWQgSW1wbGVtZW50YXRpb25cIiwgKCkgPT4ge1xuICBsZXQgYXBwOiBjZGt0Zi5BcHA7XG4gIGxldCBzdGFjazogY2RrdGYuVGVycmFmb3JtU3RhY2s7XG4gIGxldCBtYW5hZ2VyOiBBcGlWZXJzaW9uTWFuYWdlcjtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKGFwcCwgXCJUZXN0U3RhY2tcIik7XG4gICAgbWFuYWdlciA9IEFwaVZlcnNpb25NYW5hZ2VyLmluc3RhbmNlKCk7XG5cbiAgICAvLyBFbnN1cmUgUG9saWN5IERlZmluaXRpb24gc2NoZW1hcyBhcmUgcmVnaXN0ZXJlZFxuICAgIHRyeSB7XG4gICAgICBtYW5hZ2VyLnJlZ2lzdGVyUmVzb3VyY2VUeXBlKFxuICAgICAgICBQT0xJQ1lfREVGSU5JVElPTl9UWVBFLFxuICAgICAgICBBTExfUE9MSUNZX0RFRklOSVRJT05fVkVSU0lPTlMsXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBJZ25vcmUgaWYgYWxyZWFkeSByZWdpc3RlcmVkXG4gICAgfVxuICB9KTtcblxuICBkZXNjcmliZShcIkNvbnN0cnVjdG9yIGFuZCBCYXNpYyBQcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcG9saWN5IGRlZmluaXRpb24gd2l0aCBhdXRvbWF0aWMgbGF0ZXN0IHZlcnNpb24gcmVzb2x1dGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogUG9saWN5RGVmaW5pdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHtcbiAgICAgICAgICBpZjoge1xuICAgICAgICAgICAgZmllbGQ6IFwidGFnc1snRW52aXJvbm1lbnQnXVwiLFxuICAgICAgICAgICAgZXhpc3RzOiBcImZhbHNlXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICBlZmZlY3Q6IFwiZGVueVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVJbnN0YW5jZU9mKFBvbGljeURlZmluaXRpb24pO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTsgLy8gTGF0ZXN0IHZlcnNpb25cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLm5hbWUpLnRvQmUoXCJ0ZXN0LXBvbGljeVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBwb2xpY3kgZGVmaW5pdGlvbiB3aXRoIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogUG9saWN5RGVmaW5pdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5LXBpbm5lZFwiLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjEtMDYtMDFcIixcbiAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICBmaWVsZDogXCJ0eXBlXCIsXG4gICAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0LkNvbXB1dGUvdmlydHVhbE1hY2hpbmVzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICBlZmZlY3Q6IFwiYXVkaXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgcG9saWN5IGRlZmluaXRpb24gd2l0aCBhbGwgb3B0aW9uYWwgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogUG9saWN5RGVmaW5pdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5LWZ1bGxcIixcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiVGVzdCBQb2xpY3kgRGVmaW5pdGlvblwiLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJBIHRlc3QgcG9saWN5IGRlZmluaXRpb24gZm9yIHVuaXQgdGVzdGluZ1wiLFxuICAgICAgICBwb2xpY3lUeXBlOiBcIkN1c3RvbVwiLFxuICAgICAgICBtb2RlOiBcIkFsbFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcImxvY2F0aW9uXCIsXG4gICAgICAgICAgICBub3RJbjogW1wiZWFzdHVzXCIsIFwid2VzdHVzXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgZWZmZWN0OiBcImRlbnlcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgYWxsb3dlZExvY2F0aW9uczoge1xuICAgICAgICAgICAgdHlwZTogXCJBcnJheVwiLFxuICAgICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgZGlzcGxheU5hbWU6IFwiQWxsb3dlZCBsb2NhdGlvbnNcIixcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiVGhlIGxpc3Qgb2YgYWxsb3dlZCBsb2NhdGlvbnMgZm9yIHJlc291cmNlc1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgIGNhdGVnb3J5OiBcIkdlbmVyYWxcIixcbiAgICAgICAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGlnbm9yZUNoYW5nZXM6IFtcIm1ldGFkYXRhXCJdLFxuICAgICAgICBlbmFibGVWYWxpZGF0aW9uOiB0cnVlLFxuICAgICAgICBlbmFibGVNaWdyYXRpb25BbmFseXNpczogdHJ1ZSxcbiAgICAgICAgZW5hYmxlVHJhbnNmb3JtYXRpb246IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMuZGlzcGxheU5hbWUpLnRvQmUoXCJUZXN0IFBvbGljeSBEZWZpbml0aW9uXCIpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMuZGVzY3JpcHRpb24pLnRvQmUoXG4gICAgICAgIFwiQSB0ZXN0IHBvbGljeSBkZWZpbml0aW9uIGZvciB1bml0IHRlc3RpbmdcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wb2xpY3lUeXBlKS50b0JlKFwiQ3VzdG9tXCIpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMubW9kZSkudG9CZShcIkFsbFwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBhcmFtZXRlcnMpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5tZXRhZGF0YSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IG5hbWUgd2hlbiBuYW1lIGlzIG5vdCBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogUG9saWN5RGVmaW5pdGlvblByb3BzID0ge1xuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgIGVxdWFsczogXCJNaWNyb3NvZnQuU3RvcmFnZS9zdG9yYWdlQWNjb3VudHNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgIGVmZmVjdDogXCJhdWRpdFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ubmFtZSkudG9CZShcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcmVxdWlyZSBwb2xpY3lSdWxlIHRvIGJlIHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBhbnkgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgIH07XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsIHByb3BzKTtcbiAgICAgIH0pLnRvVGhyb3coXCJSZXF1aXJlZCBwcm9wZXJ0eSAncG9saWN5UnVsZScgaXMgbWlzc2luZ1wiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJGcmFtZXdvcmsgSW50ZWdyYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHJlc29sdmUgbGF0ZXN0IEFQSSB2ZXJzaW9uIGF1dG9tYXRpY2FsbHlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLmxhdGVzdFZlcnNpb24oKSkudG9CZShcIjIwMjEtMDYtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGFsbCByZWdpc3RlcmVkIEFQSSB2ZXJzaW9uc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzdXBwb3J0ZWRWZXJzaW9ucyA9IHBvbGljeURlZmluaXRpb24uc3VwcG9ydGVkVmVyc2lvbnMoKTtcbiAgICAgIGV4cGVjdChzdXBwb3J0ZWRWZXJzaW9ucykudG9Db250YWluKFwiMjAyMS0wNi0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHZhbGlkYXRlIHZlcnNpb24gc3VwcG9ydFwiLCAoKSA9PiB7XG4gICAgICAvLyBWYWxpZCB2ZXJzaW9uXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJWYWxpZFZlcnNpb25cIiwge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjEtMDYtMDFcIixcbiAgICAgICAgfSk7XG4gICAgICB9KS5ub3QudG9UaHJvdygpO1xuXG4gICAgICAvLyBJbnZhbGlkIHZlcnNpb25cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkludmFsaWRWZXJzaW9uXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIyLTAxLTAxXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdyhcIlVuc3VwcG9ydGVkIEFQSSB2ZXJzaW9uICcyMDIyLTAxLTAxJ1wiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGxvYWQgY29ycmVjdCBzY2hlbWEgZm9yIHJlc29sdmVkIHZlcnNpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGFwaVZlcnNpb246IFwiMjAyMS0wNi0wMVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24uc2NoZW1hKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24uc2NoZW1hLnJlc291cmNlVHlwZSkudG9CZShQT0xJQ1lfREVGSU5JVElPTl9UWVBFKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnNjaGVtYS52ZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnNjaGVtYS5wcm9wZXJ0aWVzKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgbG9hZCB2ZXJzaW9uIGNvbmZpZ3VyYXRpb24gY29ycmVjdGx5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnZlcnNpb25Db25maWcpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi52ZXJzaW9uQ29uZmlnLnZlcnNpb24pLnRvQmUoXCIyMDIxLTA2LTAxXCIpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24udmVyc2lvbkNvbmZpZy5zdXBwb3J0TGV2ZWwpLnRvQmUoXG4gICAgICAgIFZlcnNpb25TdXBwb3J0TGV2ZWwuQUNUSVZFLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQcm9wZXJ0eSBWYWxpZGF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB2YWxpZGF0ZSBwcm9wZXJ0aWVzIHdoZW4gdmFsaWRhdGlvbiBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBQb2xpY3lEZWZpbml0aW9uUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICBmaWVsZDogXCJ0eXBlXCIsXG4gICAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0LkNvbXB1dGUvdmlydHVhbE1hY2hpbmVzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICBlZmZlY3Q6IFwiYXVkaXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBlbmFibGVWYWxpZGF0aW9uOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiVGVzdFBvbGljeURlZmluaXRpb25cIiwgcHJvcHMpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgdmFsaWRhdGlvbiByZXN1bHRzIGZvciB2YWxpZCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidmFsaWQtcG9saWN5XCIsXG4gICAgICAgICAgZGlzcGxheU5hbWU6IFwiVmFsaWQgUG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgZW5hYmxlVmFsaWRhdGlvbjogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnZhbGlkYXRpb25SZXN1bHQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi52YWxpZGF0aW9uUmVzdWx0IS52YWxpZCkudG9CZSh0cnVlKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnZhbGlkYXRpb25SZXN1bHQhLmVycm9ycykudG9IYXZlTGVuZ3RoKDApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc2tpcCB2YWxpZGF0aW9uIHdoZW4gZGlzYWJsZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGVuYWJsZVZhbGlkYXRpb246IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiTWlncmF0aW9uIEFuYWx5c2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBza2lwIG1pZ3JhdGlvbiBhbmFseXNpcyBmb3Igc2luZ2xlIHZlcnNpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGFwaVZlcnNpb246IFwiMjAyMS0wNi0wMVwiLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgLy8gU2luY2UgdGhlcmUncyBvbmx5IG9uZSB2ZXJzaW9uLCBtaWdyYXRpb24gYW5hbHlzaXMgc2hvdWxkIGJlIHNraXBwZWRcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc2tpcCBtaWdyYXRpb24gYW5hbHlzaXMgd2hlbiBkaXNhYmxlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgZW5hYmxlTWlncmF0aW9uQW5hbHlzaXM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ubWlncmF0aW9uQW5hbHlzaXMpLnRvQmVVbmRlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJSZXNvdXJjZSBDcmVhdGlvbiBhbmQgQm9keVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGNvcnJlY3QgcmVzb3VyY2UgYm9keSB3aXRoIG1pbmltYWwgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgICAgZmllbGQ6IFwidGFnc1snRW52aXJvbm1lbnQnXVwiLFxuICAgICAgICAgICAgICBleGlzdHM6IFwiZmFsc2VcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICAgIGVmZmVjdDogXCJkZW55XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbikudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVJ1bGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgY29ycmVjdCByZXNvdXJjZSBib2R5IHdpdGggYWxsIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIlRlc3QgUG9saWN5XCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiQSB0ZXN0IHBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVR5cGU6IFwiQ3VzdG9tXCIsXG4gICAgICAgICAgbW9kZTogXCJJbmRleGVkXCIsXG4gICAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgICAgZmllbGQ6IFwibG9jYXRpb25cIixcbiAgICAgICAgICAgICAgbm90SW46IFtcImVhc3R1c1wiLCBcIndlc3R1c1wiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICAgIGVmZmVjdDogXCJkZW55XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgYWxsb3dlZExvY2F0aW9uczoge1xuICAgICAgICAgICAgICB0eXBlOiBcIkFycmF5XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIGNhdGVnb3J5OiBcIkNvbXBsaWFuY2VcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5kaXNwbGF5TmFtZSkudG9CZShcIlRlc3QgUG9saWN5XCIpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5VHlwZSkudG9CZShcIkN1c3RvbVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLm1vZGUpLnRvQmUoXCJJbmRleGVkXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3ktb3V0cHV0c1wiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24uaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlB1YmxpYyBNZXRob2RzIGFuZCBQcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICBsZXQgcG9saWN5RGVmaW5pdGlvbjogUG9saWN5RGVmaW5pdGlvbjtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICBkaXNwbGF5TmFtZTogXCJUZXN0IFBvbGljeVwiLFxuICAgICAgICBwb2xpY3lUeXBlOiBcIkN1c3RvbVwiLFxuICAgICAgICBtb2RlOiBcIkFsbFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgIGVxdWFsczogXCJNaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgIGVmZmVjdDogXCJhdWRpdFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgY29ycmVjdCBpZCBmb3JtYXRcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24uaWQpLnRvTWF0Y2goL15cXCRcXHsuKlxcLmlkXFx9JC8pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSByZXNvdXJjZUlkIHByb3BlcnR5IG1hdGNoaW5nIGlkXCIsICgpID0+IHtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnJlc291cmNlSWQpLnRvQmUocG9saWN5RGVmaW5pdGlvbi5pZCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gY29ycmVjdCBwb2xpY3lUeXBlXCIsICgpID0+IHtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnBvbGljeVR5cGUpLnRvQmUoXCJDdXN0b21cIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gY29ycmVjdCBwb2xpY3lNb2RlXCIsICgpID0+IHtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnBvbGljeU1vZGUpLnRvQmUoXCJBbGxcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBwb2xpY3lUeXBlIHdoZW4gbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRQb2xpY3kgPSBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJEZWZhdWx0VHlwZVBvbGljeVwiLCB7XG4gICAgICAgIG5hbWU6IFwiZGVmYXVsdC1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGRlZmF1bHRQb2xpY3kucG9saWN5VHlwZSkudG9CZShcIkN1c3RvbVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IG1vZGUgd2hlbiBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZGVmYXVsdFBvbGljeSA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkRlZmF1bHRNb2RlUG9saWN5XCIsIHtcbiAgICAgICAgbmFtZTogXCJkZWZhdWx0LXBvbGljeVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoZGVmYXVsdFBvbGljeS5wb2xpY3lNb2RlKS50b0JlKFwiQWxsXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIklnbm9yZSBDaGFuZ2VzIENvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGFwcGx5IGlnbm9yZSBjaGFuZ2VzIGxpZmVjeWNsZSBydWxlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIklnbm9yZUNoYW5nZXNQb2xpY3lcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJtZXRhZGF0YVwiLCBcImRlc2NyaXB0aW9uXCJdLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVJbnN0YW5jZU9mKFBvbGljeURlZmluaXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGVtcHR5IGlnbm9yZSBjaGFuZ2VzIGFycmF5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiRW1wdHlJZ25vcmVQb2xpY3lcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlSW5zdGFuY2VPZihQb2xpY3lEZWZpbml0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQb2xpY3kgUnVsZSBWYWxpZGF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhY2NlcHQgY29tcGxleCBwb2xpY3kgcnVsZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29tcGxleFJ1bGUgPSB7XG4gICAgICAgIGlmOiB7XG4gICAgICAgICAgYWxsT2Y6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmllbGQ6IFwidHlwZVwiLFxuICAgICAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0LlN0b3JhZ2Uvc3RvcmFnZUFjY291bnRzXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBmaWVsZDogXCJNaWNyb3NvZnQuU3RvcmFnZS9zdG9yYWdlQWNjb3VudHMvZW5hYmxlSHR0cHNUcmFmZmljT25seVwiLFxuICAgICAgICAgICAgICBub3RFcXVhbHM6IFwidHJ1ZVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgZWZmZWN0OiBcImRlbnlcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiQ29tcGxleFJ1bGVQb2xpY3lcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiY29tcGxleC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiBjb21wbGV4UnVsZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZSkudG9FcXVhbChjb21wbGV4UnVsZSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBhY2NlcHQgcG9saWN5IHJ1bGVzIHdpdGggcGFyYW1ldGVyc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlBhcmFtZXRlcml6ZWRQb2xpY3lcIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicGFyYW1ldGVyaXplZC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgICBpZjoge1xuICAgICAgICAgICAgICBmaWVsZDogXCJbY29uY2F0KCd0YWdzWycsIHBhcmFtZXRlcnMoJ3RhZ05hbWUnKSwgJ10nKV1cIixcbiAgICAgICAgICAgICAgZXhpc3RzOiBcImZhbHNlXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgICBlZmZlY3Q6IFwiW3BhcmFtZXRlcnMoJ2VmZmVjdCcpXVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIHRhZ05hbWU6IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJTdHJpbmdcIixcbiAgICAgICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5TmFtZTogXCJUYWcgTmFtZVwiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIk5hbWUgb2YgdGhlIHRhZyB0byBjaGVja1wiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVmZmVjdDoge1xuICAgICAgICAgICAgICB0eXBlOiBcIlN0cmluZ1wiLFxuICAgICAgICAgICAgICBhbGxvd2VkVmFsdWVzOiBbXCJhdWRpdFwiLCBcImRlbnlcIl0sXG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogXCJhdWRpdFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wYXJhbWV0ZXJzKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkVycm9yIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgaW52YWxpZCBBUEkgdmVyc2lvbnMgZ3JhY2VmdWxseVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJJbnZhbGlkQVBJXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCJpbnZhbGlkLXZlcnNpb25cIixcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KFwiVW5zdXBwb3J0ZWQgQVBJIHZlcnNpb24gJ2ludmFsaWQtdmVyc2lvbidcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgdmFsaWRhdGlvbiBlcnJvcnMgd2hlbiB2YWxpZGF0aW9uIGlzIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiVmFsaWRhdGlvbkVycm9yXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogdW5kZWZpbmVkIGFzIGFueSwgLy8gTWlzc2luZyByZXF1aXJlZCBwb2xpY3lSdWxlXG4gICAgICAgICAgZW5hYmxlVmFsaWRhdGlvbjogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KFwiUmVxdWlyZWQgcHJvcGVydHkgJ3BvbGljeVJ1bGUnIGlzIG1pc3NpbmdcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgc2NoZW1hIHJlZ2lzdHJhdGlvbiBlcnJvcnMgZ3JhY2VmdWxseVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJTY2hlbWFUZXN0XCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJKU0lJIENvbXBsaWFuY2VcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGhhdmUgSlNJSS1jb21wbGlhbnQgY29uc3RydWN0b3JcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiSnNpaVRlc3RcIiwge1xuICAgICAgICAgIG5hbWU6IFwianNpaS10ZXN0XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgSlNJSS1jb21wbGlhbnQgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiSnNpaVByb3BzXCIsIHtcbiAgICAgICAgbmFtZTogXCJqc2lpLXByb3BzXCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5pZCkudG9CZShcInN0cmluZ1wiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5uYW1lKS50b0JlKFwic3RyaW5nXCIpO1xuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcInN0cmluZ1wiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5wb2xpY3lUeXBlKS50b0JlKFwic3RyaW5nXCIpO1xuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLnBvbGljeU1vZGUpLnRvQmUoXCJzdHJpbmdcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIEpTSUktY29tcGxpYW50IG1ldGhvZHNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkpzaWlNZXRob2RzXCIsIHtcbiAgICAgICAgbmFtZTogXCJqc2lpLW1ldGhvZHNcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLmxhdGVzdFZlcnNpb24pLnRvQmUoXCJmdW5jdGlvblwiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5zdXBwb3J0ZWRWZXJzaW9ucykudG9CZShcImZ1bmN0aW9uXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc2VyaWFsaXplIGNvbXBsZXggb2JqZWN0cyBjb3JyZWN0bHlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJKc2lpU2VyaWFsaXphdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJqc2lpLXNlcmlhbGl6YXRpb25cIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgICBpZjogeyBmaWVsZDogXCJsb2NhdGlvblwiLCBlcXVhbHM6IFwiZWFzdHVzXCIgfSxcbiAgICAgICAgICAgIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgdGVzdFBhcmFtOiB7XG4gICAgICAgICAgICAgIHR5cGU6IFwiU3RyaW5nXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocG9saWN5RGVmaW5pdGlvbi52YWxpZGF0aW9uUmVzdWx0KSxcbiAgICAgICkubm90LnRvVGhyb3coKTtcbiAgICAgIGV4cGVjdCgoKSA9PiBKU09OLnN0cmluZ2lmeShwb2xpY3lEZWZpbml0aW9uLnNjaGVtYSkpLm5vdC50b1Rocm93KCk7XG4gICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocG9saWN5RGVmaW5pdGlvbi52ZXJzaW9uQ29uZmlnKSxcbiAgICAgICkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgVGVycmFmb3JtIEludGVncmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHRvIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlN5bnRoVGVzdFwiLCB7XG4gICAgICAgIG5hbWU6IFwic3ludGgtdGVzdFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgIGVxdWFsczogXCJNaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgIGVmZmVjdDogXCJhdWRpdFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9CZURlZmluZWQoKTtcblxuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHdvcmsgaW4gY29tcGxleCBDREsgY29uc3RydWN0c1wiLCAoKSA9PiB7XG4gICAgICBjbGFzcyBDb21wbGV4Q29uc3RydWN0IGV4dGVuZHMgY2RrdGYuVGVycmFmb3JtU3RhY2sge1xuICAgICAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrdGYuQXBwLCBpZDogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgICAgICAgIGNvbnN0IHBvbGljeTEgPSBuZXcgUG9saWN5RGVmaW5pdGlvbih0aGlzLCBcIlBvbGljeTFcIiwge1xuICAgICAgICAgICAgbmFtZTogXCJwb2xpY3ktMVwiLFxuICAgICAgICAgICAgZGlzcGxheU5hbWU6IFwiRmlyc3QgUG9saWN5XCIsXG4gICAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBwb2xpY3kyID0gbmV3IFBvbGljeURlZmluaXRpb24odGhpcywgXCJQb2xpY3kyXCIsIHtcbiAgICAgICAgICAgIG5hbWU6IFwicG9saWN5LTJcIixcbiAgICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIlNlY29uZCBQb2xpY3lcIixcbiAgICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBuZXcgY2RrdGYuVGVycmFmb3JtT3V0cHV0KHRoaXMsIFwiUG9saWN5MUlkXCIsIHtcbiAgICAgICAgICAgIHZhbHVlOiBwb2xpY3kxLmlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbmV3IGNka3RmLlRlcnJhZm9ybU91dHB1dCh0aGlzLCBcIlBvbGljeTJJZFwiLCB7XG4gICAgICAgICAgICB2YWx1ZTogcG9saWN5Mi5pZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQ29tcGxleENvbnN0cnVjdChhcHAsIFwiQ29tcGxleFN0YWNrXCIpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBwb2xpY3kgZGVmaW5pdGlvbnMgaW4gdGhlIHNhbWUgc3RhY2tcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5MSA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlBvbGljeURlZmluaXRpb24xXCIsIHtcbiAgICAgICAgbmFtZTogXCJwb2xpY3ktMVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcG9saWN5MiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlBvbGljeURlZmluaXRpb24yXCIsIHtcbiAgICAgICAgbmFtZTogXCJwb2xpY3ktMlwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHBvbGljeTEucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3kyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUG9saWN5IERlZmluaXRpb24gVHlwZXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgQnVpbHRJbiBwb2xpY3kgdHlwZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiQnVpbHRJblBvbGljeVwiLCB7XG4gICAgICAgIG5hbWU6IFwiYnVpbHRpbi1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJCdWlsdEluXCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJhdWRpdFwiIH0gfSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wb2xpY3lUeXBlKS50b0JlKFwiQnVpbHRJblwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgU3RhdGljIHBvbGljeSB0eXBlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJTdGF0aWNQb2xpY3lcIiwge1xuICAgICAgICBuYW1lOiBcInN0YXRpYy1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJTdGF0aWNcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImF1ZGl0XCIgfSB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnBvbGljeVR5cGUpLnRvQmUoXCJTdGF0aWNcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGRpZmZlcmVudCBwb2xpY3kgbW9kZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZXhlZFBvbGljeSA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkluZGV4ZWRQb2xpY3lcIiwge1xuICAgICAgICBuYW1lOiBcImluZGV4ZWQtcG9saWN5XCIsXG4gICAgICAgIG1vZGU6IFwiSW5kZXhlZFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGluZGV4ZWRQb2xpY3kucG9saWN5TW9kZSkudG9CZShcIkluZGV4ZWRcIik7XG5cbiAgICAgIGNvbnN0IHJlc291cmNlUHJvdmlkZXJQb2xpY3kgPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUmVzb3VyY2VQcm92aWRlclBvbGljeVwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJyZXNvdXJjZS1wcm92aWRlci1wb2xpY3lcIixcbiAgICAgICAgICBtb2RlOiBcIk1pY3Jvc29mdC5LZXlWYXVsdC5EYXRhXCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImF1ZGl0XCIgfSB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHJlc291cmNlUHJvdmlkZXJQb2xpY3kucG9saWN5TW9kZSkudG9CZShcIk1pY3Jvc29mdC5LZXlWYXVsdC5EYXRhXCIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|