@microsoft/terraform-cdk-constructs 1.0.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 +89270 -15866
- package/API.md +103201 -10557
- package/README.md +72 -36
- package/docs/monitoring-guide.md +206 -0
- package/docs/testing.md +84 -1
- package/lib/azure-actiongroup/index.d.ts +1 -0
- package/lib/azure-actiongroup/index.js +18 -0
- package/lib/azure-actiongroup/lib/action-group-schemas.d.ts +24 -0
- package/lib/azure-actiongroup/lib/action-group-schemas.js +201 -0
- package/lib/azure-actiongroup/lib/action-group.d.ts +302 -0
- package/lib/azure-actiongroup/lib/action-group.js +175 -0
- package/lib/azure-actiongroup/lib/index.d.ts +2 -0
- package/lib/azure-actiongroup/lib/index.js +19 -0
- package/lib/azure-actiongroup/test/action-group.integ.d.ts +9 -0
- package/lib/azure-actiongroup/test/action-group.integ.js +79 -0
- package/lib/azure-actiongroup/test/action-group.spec.d.ts +8 -0
- package/lib/azure-actiongroup/test/action-group.spec.js +602 -0
- package/lib/azure-activitylogalert/index.d.ts +1 -0
- package/lib/azure-activitylogalert/index.js +18 -0
- package/lib/azure-activitylogalert/lib/activity-log-alert-schemas.d.ts +24 -0
- package/lib/azure-activitylogalert/lib/activity-log-alert-schemas.js +182 -0
- package/lib/azure-activitylogalert/lib/activity-log-alert.d.ts +226 -0
- package/lib/azure-activitylogalert/lib/activity-log-alert.js +186 -0
- package/lib/azure-activitylogalert/lib/index.d.ts +2 -0
- package/lib/azure-activitylogalert/lib/index.js +19 -0
- package/lib/azure-activitylogalert/test/activity-log-alert.integ.d.ts +9 -0
- package/lib/azure-activitylogalert/test/activity-log-alert.integ.js +98 -0
- package/lib/azure-activitylogalert/test/activity-log-alert.spec.d.ts +9 -0
- package/lib/azure-activitylogalert/test/activity-log-alert.spec.js +1101 -0
- package/lib/azure-aks/index.d.ts +1 -0
- package/lib/azure-aks/index.js +18 -0
- package/lib/azure-aks/lib/aks-cluster-schemas.d.ts +505 -0
- package/lib/azure-aks/lib/aks-cluster-schemas.js +572 -0
- package/lib/azure-aks/lib/aks-cluster.d.ts +386 -0
- package/lib/azure-aks/lib/aks-cluster.js +466 -0
- package/lib/azure-aks/lib/index.d.ts +2 -0
- package/lib/azure-aks/lib/index.js +19 -0
- package/lib/azure-aks/test/aks-cluster.integ.d.ts +9 -0
- package/lib/azure-aks/test/aks-cluster.integ.js +260 -0
- package/lib/azure-aks/test/aks-cluster.spec.d.ts +8 -0
- package/lib/azure-aks/test/aks-cluster.spec.js +1396 -0
- package/lib/azure-diagnosticsettings/index.d.ts +1 -0
- package/lib/azure-diagnosticsettings/index.js +18 -0
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings-schemas.d.ts +50 -0
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings-schemas.js +207 -0
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings.d.ts +183 -0
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +174 -0
- package/lib/azure-diagnosticsettings/lib/index.d.ts +2 -0
- package/lib/azure-diagnosticsettings/lib/index.js +19 -0
- package/lib/azure-diagnosticsettings/test/diagnostic-settings.spec.d.ts +8 -0
- package/lib/azure-diagnosticsettings/test/diagnostic-settings.spec.js +432 -0
- 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 +1 -0
- package/lib/azure-metricalert/index.js +18 -0
- package/lib/azure-metricalert/lib/index.d.ts +2 -0
- package/lib/azure-metricalert/lib/index.js +19 -0
- package/lib/azure-metricalert/lib/metric-alert-schemas.d.ts +24 -0
- package/lib/azure-metricalert/lib/metric-alert-schemas.js +242 -0
- package/lib/azure-metricalert/lib/metric-alert.d.ts +334 -0
- package/lib/azure-metricalert/lib/metric-alert.js +226 -0
- package/lib/azure-metricalert/test/metric-alert.integ.d.ts +9 -0
- package/lib/azure-metricalert/test/metric-alert.integ.js +123 -0
- package/lib/azure-metricalert/test/metric-alert.spec.d.ts +9 -0
- package/lib/azure-metricalert/test/metric-alert.spec.js +1266 -0
- package/lib/azure-networkinterface/index.d.ts +1 -0
- package/lib/azure-networkinterface/index.js +18 -0
- package/lib/azure-networkinterface/lib/index.d.ts +2 -0
- package/lib/azure-networkinterface/lib/index.js +19 -0
- package/lib/azure-networkinterface/lib/network-interface-schemas.d.ts +32 -0
- package/lib/azure-networkinterface/lib/network-interface-schemas.js +222 -0
- package/lib/azure-networkinterface/lib/network-interface.d.ts +260 -0
- package/lib/azure-networkinterface/lib/network-interface.js +213 -0
- package/lib/azure-networkinterface/test/network-interface.integ.d.ts +9 -0
- package/lib/azure-networkinterface/test/network-interface.integ.js +116 -0
- package/lib/azure-networkinterface/test/network-interface.spec.d.ts +8 -0
- package/lib/azure-networkinterface/test/network-interface.spec.js +655 -0
- package/lib/azure-networksecuritygroup/index.d.ts +1 -0
- package/lib/azure-networksecuritygroup/index.js +18 -0
- package/lib/azure-networksecuritygroup/lib/index.d.ts +2 -0
- package/lib/azure-networksecuritygroup/lib/index.js +19 -0
- package/lib/azure-networksecuritygroup/lib/network-security-group-schemas.d.ts +32 -0
- package/lib/azure-networksecuritygroup/lib/network-security-group-schemas.js +198 -0
- package/lib/azure-networksecuritygroup/lib/network-security-group.d.ts +259 -0
- package/lib/azure-networksecuritygroup/lib/network-security-group.js +226 -0
- package/lib/azure-networksecuritygroup/test/network-security-group.integ.d.ts +9 -0
- package/lib/azure-networksecuritygroup/test/network-security-group.integ.js +151 -0
- package/lib/azure-networksecuritygroup/test/network-security-group.spec.d.ts +8 -0
- package/lib/azure-networksecuritygroup/test/network-security-group.spec.js +652 -0
- 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 +1 -0
- package/lib/azure-publicipaddress/index.js +18 -0
- package/lib/azure-publicipaddress/lib/index.d.ts +2 -0
- package/lib/azure-publicipaddress/lib/index.js +19 -0
- package/lib/azure-publicipaddress/lib/public-ip-address-schemas.d.ts +32 -0
- package/lib/azure-publicipaddress/lib/public-ip-address-schemas.js +227 -0
- package/lib/azure-publicipaddress/lib/public-ip-address.d.ts +247 -0
- package/lib/azure-publicipaddress/lib/public-ip-address.js +245 -0
- package/lib/azure-publicipaddress/test/public-ip-address.integ.d.ts +9 -0
- package/lib/azure-publicipaddress/test/public-ip-address.integ.js +75 -0
- package/lib/azure-publicipaddress/test/public-ip-address.spec.d.ts +15 -0
- package/lib/azure-publicipaddress/test/public-ip-address.spec.js +498 -0
- 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.integ.js +23 -11
- 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-schemas.d.ts +98 -0
- package/lib/azure-storageaccount/lib/storage-account-schemas.js +1 -1
- package/lib/azure-storageaccount/lib/storage-account.d.ts +40 -8
- package/lib/azure-storageaccount/lib/storage-account.js +145 -23
- package/lib/azure-storageaccount/test/storage-account.integ.js +91 -12
- package/lib/azure-subnet/index.d.ts +1 -0
- package/lib/azure-subnet/index.js +18 -0
- package/lib/azure-subnet/lib/index.d.ts +2 -0
- package/lib/azure-subnet/lib/index.js +19 -0
- package/lib/azure-subnet/lib/subnet-schemas.d.ts +32 -0
- package/lib/azure-subnet/lib/subnet-schemas.js +237 -0
- package/lib/azure-subnet/lib/subnet.d.ts +274 -0
- package/lib/azure-subnet/lib/subnet.js +235 -0
- package/lib/azure-subnet/test/subnet.integ.d.ts +11 -0
- package/lib/azure-subnet/test/subnet.integ.js +92 -0
- package/lib/azure-subnet/test/subnet.spec.d.ts +8 -0
- package/lib/azure-subnet/test/subnet.spec.js +395 -0
- package/lib/azure-virtualmachine/index.d.ts +1 -0
- package/lib/azure-virtualmachine/index.js +18 -0
- package/lib/azure-virtualmachine/lib/index.d.ts +2 -0
- package/lib/azure-virtualmachine/lib/index.js +19 -0
- package/lib/azure-virtualmachine/lib/virtual-machine-schemas.d.ts +327 -0
- package/lib/azure-virtualmachine/lib/virtual-machine-schemas.js +544 -0
- package/lib/azure-virtualmachine/lib/virtual-machine.d.ts +368 -0
- package/lib/azure-virtualmachine/lib/virtual-machine.js +441 -0
- package/lib/azure-virtualmachine/test/virtual-machine.integ.d.ts +9 -0
- package/lib/azure-virtualmachine/test/virtual-machine.integ.js +220 -0
- package/lib/azure-virtualmachine/test/virtual-machine.spec.d.ts +9 -0
- package/lib/azure-virtualmachine/test/virtual-machine.spec.js +1032 -0
- package/lib/azure-virtualnetwork/index.d.ts +1 -0
- package/lib/azure-virtualnetwork/index.js +18 -0
- package/lib/azure-virtualnetwork/lib/index.d.ts +2 -0
- package/lib/azure-virtualnetwork/lib/index.js +19 -0
- package/lib/azure-virtualnetwork/lib/virtual-network-schemas.d.ts +32 -0
- package/lib/azure-virtualnetwork/lib/virtual-network-schemas.js +236 -0
- package/lib/azure-virtualnetwork/lib/virtual-network.d.ts +204 -0
- package/lib/azure-virtualnetwork/lib/virtual-network.js +224 -0
- package/lib/azure-virtualnetwork/test/virtual-network.integ.d.ts +9 -0
- package/lib/azure-virtualnetwork/test/virtual-network.integ.js +91 -0
- package/lib/azure-virtualnetwork/test/virtual-network.spec.d.ts +8 -0
- package/lib/azure-virtualnetwork/test/virtual-network.spec.js +398 -0
- 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 +1 -0
- package/lib/azure-vmss/index.js +18 -0
- package/lib/azure-vmss/lib/index.d.ts +2 -0
- package/lib/azure-vmss/lib/index.js +19 -0
- package/lib/azure-vmss/lib/virtual-machine-scale-set.d.ts +250 -0
- package/lib/azure-vmss/lib/virtual-machine-scale-set.js +479 -0
- package/lib/azure-vmss/lib/vmss-schemas.d.ts +472 -0
- package/lib/azure-vmss/lib/vmss-schemas.js +444 -0
- package/lib/azure-vmss/test/virtual-machine-scale-set.integ.d.ts +15 -0
- package/lib/azure-vmss/test/virtual-machine-scale-set.integ.js +261 -0
- package/lib/azure-vmss/test/virtual-machine-scale-set.spec.d.ts +8 -0
- package/lib/azure-vmss/test/virtual-machine-scale-set.spec.js +997 -0
- 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 +268 -48
- package/lib/core-azure/lib/azapi/azapi-resource.js +411 -136
- 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.d.ts +33 -21
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +69 -27
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.d.ts +134 -120
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +209 -59
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-action/index.d.ts +141 -128
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-action/index.js +183 -36
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-id/index.d.ts +55 -43
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-id/index.js +94 -26
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-list/index.d.ts +129 -116
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource-list/index.js +155 -32
- package/lib/core-azure/lib/azapi/providers-azapi/data-plane-resource/index.d.ts +187 -174
- package/lib/core-azure/lib/azapi/providers-azapi/data-plane-resource/index.js +267 -48
- package/lib/core-azure/lib/azapi/providers-azapi/index.d.ts +10 -10
- package/lib/core-azure/lib/azapi/providers-azapi/index.js +1 -1
- package/lib/core-azure/lib/azapi/providers-azapi/lazy-index.d.ts +0 -0
- package/lib/core-azure/lib/azapi/providers-azapi/lazy-index.js +13 -0
- package/lib/core-azure/lib/azapi/providers-azapi/provider/index.d.ts +174 -162
- package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +278 -16
- package/lib/core-azure/lib/azapi/providers-azapi/resource/index.d.ts +239 -225
- package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +360 -76
- package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.d.ts +163 -150
- package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +221 -46
- package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.d.ts +162 -149
- package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +249 -50
- 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 +13 -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 +56 -0
- package/lib/index.js +59 -2
- package/lib/testing/index.d.ts +92 -2
- package/lib/testing/index.js +258 -18
- package/lib/testing/lib/cleanup.d.ts +230 -0
- package/lib/testing/lib/cleanup.js +338 -0
- package/lib/testing/lib/metadata.d.ts +151 -0
- package/lib/testing/lib/metadata.js +183 -0
- package/lib/testing/lib/naming.d.ts +96 -0
- package/lib/testing/lib/naming.js +336 -0
- package/node_modules/uuid/LICENSE.md +9 -0
- package/node_modules/uuid/README.md +510 -0
- package/node_modules/uuid/dist/cjs/index.d.ts +15 -0
- package/node_modules/uuid/dist/cjs/index.js +31 -0
- package/node_modules/uuid/dist/cjs/max.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/max.js +3 -0
- package/node_modules/uuid/dist/cjs/md5.d.ts +4 -0
- package/node_modules/uuid/dist/cjs/md5.js +13 -0
- package/node_modules/uuid/dist/cjs/native.d.ts +6 -0
- package/node_modules/uuid/dist/cjs/native.js +4 -0
- package/node_modules/uuid/dist/cjs/nil.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/nil.js +3 -0
- package/node_modules/uuid/dist/cjs/package.json +1 -0
- package/node_modules/uuid/dist/cjs/parse.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/parse.js +11 -0
- package/node_modules/uuid/dist/cjs/regex.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/regex.js +3 -0
- package/node_modules/uuid/dist/cjs/rng.d.ts +1 -0
- package/node_modules/uuid/dist/cjs/rng.js +13 -0
- package/node_modules/uuid/dist/cjs/sha1.d.ts +4 -0
- package/node_modules/uuid/dist/cjs/sha1.js +13 -0
- package/node_modules/uuid/dist/cjs/stringify.d.ts +3 -0
- package/node_modules/uuid/dist/cjs/stringify.js +39 -0
- package/node_modules/uuid/dist/cjs/types.d.ts +21 -0
- package/node_modules/uuid/dist/cjs/types.js +2 -0
- package/node_modules/uuid/dist/cjs/uuid-bin.d.ts +1 -0
- package/node_modules/uuid/dist/cjs/uuid-bin.js +72 -0
- package/node_modules/uuid/dist/cjs/v1.d.ts +11 -0
- package/node_modules/uuid/dist/cjs/v1.js +87 -0
- package/node_modules/uuid/dist/cjs/v1ToV6.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/v1ToV6.js +13 -0
- package/node_modules/uuid/dist/cjs/v3.d.ts +9 -0
- package/node_modules/uuid/dist/cjs/v3.js +14 -0
- package/node_modules/uuid/dist/cjs/v35.d.ts +7 -0
- package/node_modules/uuid/dist/cjs/v35.js +41 -0
- package/node_modules/uuid/dist/cjs/v4.d.ts +4 -0
- package/node_modules/uuid/dist/cjs/v4.js +29 -0
- package/node_modules/uuid/dist/cjs/v5.d.ts +9 -0
- package/node_modules/uuid/dist/cjs/v5.js +14 -0
- package/node_modules/uuid/dist/cjs/v6.d.ts +4 -0
- package/node_modules/uuid/dist/cjs/v6.js +19 -0
- package/node_modules/uuid/dist/cjs/v6ToV1.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/v6ToV1.js +13 -0
- package/node_modules/uuid/dist/cjs/v7.d.ts +9 -0
- package/node_modules/uuid/dist/cjs/v7.js +69 -0
- package/node_modules/uuid/dist/cjs/validate.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/validate.js +7 -0
- package/node_modules/uuid/dist/cjs/version.d.ts +2 -0
- package/node_modules/uuid/dist/cjs/version.js +10 -0
- package/node_modules/uuid/dist/cjs-browser/index.d.ts +15 -0
- package/node_modules/uuid/dist/cjs-browser/index.js +31 -0
- package/node_modules/uuid/dist/cjs-browser/max.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/max.js +3 -0
- package/node_modules/uuid/dist/cjs-browser/md5.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/md5.js +137 -0
- package/node_modules/uuid/dist/cjs-browser/native.d.ts +4 -0
- package/node_modules/uuid/dist/cjs-browser/native.js +4 -0
- package/node_modules/uuid/dist/cjs-browser/nil.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/nil.js +3 -0
- package/node_modules/uuid/dist/cjs-browser/package.json +1 -0
- package/node_modules/uuid/dist/cjs-browser/parse.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/parse.js +11 -0
- package/node_modules/uuid/dist/cjs-browser/regex.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/regex.js +3 -0
- package/node_modules/uuid/dist/cjs-browser/rng.d.ts +1 -0
- package/node_modules/uuid/dist/cjs-browser/rng.js +14 -0
- package/node_modules/uuid/dist/cjs-browser/sha1.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/sha1.js +72 -0
- package/node_modules/uuid/dist/cjs-browser/stringify.d.ts +3 -0
- package/node_modules/uuid/dist/cjs-browser/stringify.js +39 -0
- package/node_modules/uuid/dist/cjs-browser/types.d.ts +21 -0
- package/node_modules/uuid/dist/cjs-browser/types.js +2 -0
- package/node_modules/uuid/dist/cjs-browser/uuid-bin.d.ts +1 -0
- package/node_modules/uuid/dist/cjs-browser/uuid-bin.js +72 -0
- package/node_modules/uuid/dist/cjs-browser/v1.d.ts +11 -0
- package/node_modules/uuid/dist/cjs-browser/v1.js +87 -0
- package/node_modules/uuid/dist/cjs-browser/v1ToV6.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/v1ToV6.js +13 -0
- package/node_modules/uuid/dist/cjs-browser/v3.d.ts +9 -0
- package/node_modules/uuid/dist/cjs-browser/v3.js +14 -0
- package/node_modules/uuid/dist/cjs-browser/v35.d.ts +7 -0
- package/node_modules/uuid/dist/cjs-browser/v35.js +41 -0
- package/node_modules/uuid/dist/cjs-browser/v4.d.ts +4 -0
- package/node_modules/uuid/dist/cjs-browser/v4.js +29 -0
- package/node_modules/uuid/dist/cjs-browser/v5.d.ts +9 -0
- package/node_modules/uuid/dist/cjs-browser/v5.js +14 -0
- package/node_modules/uuid/dist/cjs-browser/v6.d.ts +4 -0
- package/node_modules/uuid/dist/cjs-browser/v6.js +19 -0
- package/node_modules/uuid/dist/cjs-browser/v6ToV1.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/v6ToV1.js +13 -0
- package/node_modules/uuid/dist/cjs-browser/v7.d.ts +9 -0
- package/node_modules/uuid/dist/cjs-browser/v7.js +69 -0
- package/node_modules/uuid/dist/cjs-browser/validate.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/validate.js +7 -0
- package/node_modules/uuid/dist/cjs-browser/version.d.ts +2 -0
- package/node_modules/uuid/dist/cjs-browser/version.js +10 -0
- package/node_modules/uuid/dist/esm/bin/uuid +2 -0
- package/node_modules/uuid/dist/esm/index.d.ts +15 -0
- package/node_modules/uuid/dist/esm/index.js +14 -0
- package/node_modules/uuid/dist/esm/max.d.ts +2 -0
- package/node_modules/uuid/dist/esm/max.js +1 -0
- package/node_modules/uuid/dist/esm/md5.d.ts +4 -0
- package/node_modules/uuid/dist/esm/md5.js +11 -0
- package/node_modules/uuid/dist/esm/native.d.ts +6 -0
- package/node_modules/uuid/dist/esm/native.js +2 -0
- package/node_modules/uuid/dist/esm/nil.d.ts +2 -0
- package/node_modules/uuid/dist/esm/nil.js +1 -0
- package/node_modules/uuid/dist/esm/parse.d.ts +2 -0
- package/node_modules/uuid/dist/esm/parse.js +9 -0
- package/node_modules/uuid/dist/esm/regex.d.ts +2 -0
- package/node_modules/uuid/dist/esm/regex.js +1 -0
- package/node_modules/uuid/dist/esm/rng.d.ts +1 -0
- package/node_modules/uuid/dist/esm/rng.js +10 -0
- package/node_modules/uuid/dist/esm/sha1.d.ts +4 -0
- package/node_modules/uuid/dist/esm/sha1.js +11 -0
- package/node_modules/uuid/dist/esm/stringify.d.ts +3 -0
- package/node_modules/uuid/dist/esm/stringify.js +35 -0
- package/node_modules/uuid/dist/esm/types.d.ts +21 -0
- package/node_modules/uuid/dist/esm/types.js +1 -0
- package/node_modules/uuid/dist/esm/uuid-bin.d.ts +1 -0
- package/node_modules/uuid/dist/esm/uuid-bin.js +70 -0
- package/node_modules/uuid/dist/esm/v1.d.ts +11 -0
- package/node_modules/uuid/dist/esm/v1.js +83 -0
- package/node_modules/uuid/dist/esm/v1ToV6.d.ts +2 -0
- package/node_modules/uuid/dist/esm/v1ToV6.js +10 -0
- package/node_modules/uuid/dist/esm/v3.d.ts +9 -0
- package/node_modules/uuid/dist/esm/v3.js +9 -0
- package/node_modules/uuid/dist/esm/v35.d.ts +7 -0
- package/node_modules/uuid/dist/esm/v35.js +36 -0
- package/node_modules/uuid/dist/esm/v4.d.ts +4 -0
- package/node_modules/uuid/dist/esm/v4.js +27 -0
- package/node_modules/uuid/dist/esm/v5.d.ts +9 -0
- package/node_modules/uuid/dist/esm/v5.js +9 -0
- package/node_modules/uuid/dist/esm/v6.d.ts +4 -0
- package/node_modules/uuid/dist/esm/v6.js +17 -0
- package/node_modules/uuid/dist/esm/v6ToV1.d.ts +2 -0
- package/node_modules/uuid/dist/esm/v6ToV1.js +10 -0
- package/node_modules/uuid/dist/esm/v7.d.ts +9 -0
- package/node_modules/uuid/dist/esm/v7.js +65 -0
- package/node_modules/uuid/dist/esm/validate.d.ts +2 -0
- package/node_modules/uuid/dist/esm/validate.js +5 -0
- package/node_modules/uuid/dist/esm/version.d.ts +2 -0
- package/node_modules/uuid/dist/esm/version.js +8 -0
- package/node_modules/uuid/dist/esm-browser/index.d.ts +15 -0
- package/node_modules/uuid/dist/esm-browser/index.js +14 -0
- package/node_modules/uuid/dist/esm-browser/max.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/max.js +1 -0
- package/node_modules/uuid/dist/esm-browser/md5.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/md5.js +135 -0
- package/node_modules/uuid/dist/esm-browser/native.d.ts +4 -0
- package/node_modules/uuid/dist/esm-browser/native.js +2 -0
- package/node_modules/uuid/dist/esm-browser/nil.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/nil.js +1 -0
- package/node_modules/uuid/dist/esm-browser/parse.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/parse.js +9 -0
- package/node_modules/uuid/dist/esm-browser/regex.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/regex.js +1 -0
- package/node_modules/uuid/dist/esm-browser/rng.d.ts +1 -0
- package/node_modules/uuid/dist/esm-browser/rng.js +11 -0
- package/node_modules/uuid/dist/esm-browser/sha1.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/sha1.js +70 -0
- package/node_modules/uuid/dist/esm-browser/stringify.d.ts +3 -0
- package/node_modules/uuid/dist/esm-browser/stringify.js +35 -0
- package/node_modules/uuid/dist/esm-browser/types.d.ts +21 -0
- package/node_modules/uuid/dist/esm-browser/types.js +1 -0
- package/node_modules/uuid/dist/esm-browser/uuid-bin.d.ts +1 -0
- package/node_modules/uuid/dist/esm-browser/uuid-bin.js +70 -0
- package/node_modules/uuid/dist/esm-browser/v1.d.ts +11 -0
- package/node_modules/uuid/dist/esm-browser/v1.js +83 -0
- package/node_modules/uuid/dist/esm-browser/v1ToV6.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/v1ToV6.js +10 -0
- package/node_modules/uuid/dist/esm-browser/v3.d.ts +9 -0
- package/node_modules/uuid/dist/esm-browser/v3.js +9 -0
- package/node_modules/uuid/dist/esm-browser/v35.d.ts +7 -0
- package/node_modules/uuid/dist/esm-browser/v35.js +36 -0
- package/node_modules/uuid/dist/esm-browser/v4.d.ts +4 -0
- package/node_modules/uuid/dist/esm-browser/v4.js +27 -0
- package/node_modules/uuid/dist/esm-browser/v5.d.ts +9 -0
- package/node_modules/uuid/dist/esm-browser/v5.js +9 -0
- package/node_modules/uuid/dist/esm-browser/v6.d.ts +4 -0
- package/node_modules/uuid/dist/esm-browser/v6.js +17 -0
- package/node_modules/uuid/dist/esm-browser/v6ToV1.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/v6ToV1.js +10 -0
- package/node_modules/uuid/dist/esm-browser/v7.d.ts +9 -0
- package/node_modules/uuid/dist/esm-browser/v7.js +65 -0
- package/node_modules/uuid/dist/esm-browser/validate.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/validate.js +5 -0
- package/node_modules/uuid/dist/esm-browser/version.d.ts +2 -0
- package/node_modules/uuid/dist/esm-browser/version.js +8 -0
- package/node_modules/uuid/package.json +132 -0
- package/package.json +17 -12
- package/scripts/cleanup-test-resources.ts +387 -0
- package/scripts/generate-index.js +25 -8
|
@@ -0,0 +1,1652 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Comprehensive tests for the Virtual Network Manager implementation
|
|
4
|
+
*
|
|
5
|
+
* This test suite validates the VirtualNetworkManager class and all child resource
|
|
6
|
+
* constructs using the AzapiResource framework. Tests cover automatic version resolution,
|
|
7
|
+
* explicit version pinning, schema validation, property transformation, resource creation,
|
|
8
|
+
* and parent-child relationships.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const cdktf_1 = require("cdktf");
|
|
12
|
+
const cdktf = require("cdktf");
|
|
13
|
+
const connectivity_configuration_1 = require("../lib/connectivity-configuration");
|
|
14
|
+
const network_group_1 = require("../lib/network-group");
|
|
15
|
+
const network_group_static_member_1 = require("../lib/network-group-static-member");
|
|
16
|
+
const security_admin_configuration_1 = require("../lib/security-admin-configuration");
|
|
17
|
+
const security_admin_rule_1 = require("../lib/security-admin-rule");
|
|
18
|
+
const security_admin_rule_collection_1 = require("../lib/security-admin-rule-collection");
|
|
19
|
+
const virtual_network_manager_1 = require("../lib/virtual-network-manager");
|
|
20
|
+
describe("VirtualNetworkManager", () => {
|
|
21
|
+
let app;
|
|
22
|
+
let stack;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
app = cdktf_1.Testing.app();
|
|
25
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
26
|
+
});
|
|
27
|
+
describe("Basic Instantiation Tests", () => {
|
|
28
|
+
it("should create a Virtual Network Manager with minimum required properties", () => {
|
|
29
|
+
const props = {
|
|
30
|
+
name: "test-network-manager",
|
|
31
|
+
location: "eastus",
|
|
32
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
33
|
+
networkManagerScopes: {
|
|
34
|
+
subscriptions: [
|
|
35
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
39
|
+
};
|
|
40
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
41
|
+
expect(manager).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
|
|
42
|
+
expect(manager.props).toBe(props);
|
|
43
|
+
expect(manager.resourceName).toBeDefined();
|
|
44
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
45
|
+
expect(synthesized).toContain("Microsoft.Network/networkManagers");
|
|
46
|
+
});
|
|
47
|
+
it("should create a Virtual Network Manager with all properties", () => {
|
|
48
|
+
const props = {
|
|
49
|
+
name: "test-network-manager-full",
|
|
50
|
+
location: "westus",
|
|
51
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
52
|
+
networkManagerScopes: {
|
|
53
|
+
subscriptions: [
|
|
54
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
55
|
+
],
|
|
56
|
+
managementGroups: [
|
|
57
|
+
"/providers/Microsoft.Management/managementGroups/mg1",
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
61
|
+
description: "Test network manager with all properties",
|
|
62
|
+
tags: {
|
|
63
|
+
environment: "test",
|
|
64
|
+
project: "cdktf-constructs",
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
68
|
+
expect(manager.props).toBe(props);
|
|
69
|
+
expect(manager.props.description).toBe("Test network manager with all properties");
|
|
70
|
+
expect(manager.props.tags).toEqual({
|
|
71
|
+
environment: "test",
|
|
72
|
+
project: "cdktf-constructs",
|
|
73
|
+
});
|
|
74
|
+
expect(manager.tags).toEqual(props.tags);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("Framework Integration Tests", () => {
|
|
78
|
+
it("should use default API version when none specified", () => {
|
|
79
|
+
const props = {
|
|
80
|
+
name: "test-network-manager",
|
|
81
|
+
location: "eastus",
|
|
82
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
83
|
+
networkManagerScopes: {
|
|
84
|
+
subscriptions: [
|
|
85
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
89
|
+
};
|
|
90
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
91
|
+
expect(manager.resolvedApiVersion).toBe("2024-05-01");
|
|
92
|
+
});
|
|
93
|
+
it("should use specified API version when provided", () => {
|
|
94
|
+
const props = {
|
|
95
|
+
name: "test-network-manager",
|
|
96
|
+
location: "eastus",
|
|
97
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
98
|
+
apiVersion: "2023-11-01",
|
|
99
|
+
networkManagerScopes: {
|
|
100
|
+
subscriptions: [
|
|
101
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
105
|
+
};
|
|
106
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
107
|
+
expect(manager.resolvedApiVersion).toBe("2023-11-01");
|
|
108
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
109
|
+
expect(synthesized).toContain("@2023-11-01");
|
|
110
|
+
});
|
|
111
|
+
it("should register schemas on first instantiation", () => {
|
|
112
|
+
const props = {
|
|
113
|
+
name: "test-network-manager",
|
|
114
|
+
location: "eastus",
|
|
115
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
116
|
+
networkManagerScopes: {
|
|
117
|
+
subscriptions: [
|
|
118
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
122
|
+
};
|
|
123
|
+
// First instantiation should register schemas
|
|
124
|
+
const manager1 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager1", props);
|
|
125
|
+
expect(manager1).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
|
|
126
|
+
// Second instantiation should not re-register
|
|
127
|
+
const manager2 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager2", {
|
|
128
|
+
...props,
|
|
129
|
+
name: "test-network-manager-2",
|
|
130
|
+
});
|
|
131
|
+
expect(manager2).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe("Property Validation Tests", () => {
|
|
135
|
+
it("should properly format networkManagerScopes with subscriptions", () => {
|
|
136
|
+
const props = {
|
|
137
|
+
name: "test-network-manager",
|
|
138
|
+
location: "eastus",
|
|
139
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
140
|
+
networkManagerScopes: {
|
|
141
|
+
subscriptions: [
|
|
142
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
143
|
+
"/subscriptions/11111111-1111-1111-1111-111111111111",
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
147
|
+
};
|
|
148
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
149
|
+
expect(manager.props.networkManagerScopes.subscriptions).toHaveLength(2);
|
|
150
|
+
expect(manager.props.networkManagerScopes.subscriptions).toContain("/subscriptions/00000000-0000-0000-0000-000000000000");
|
|
151
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
152
|
+
const stackConfig = JSON.parse(synthesized);
|
|
153
|
+
expect(stackConfig.resource).toBeDefined();
|
|
154
|
+
});
|
|
155
|
+
it("should properly format networkManagerScopes with management groups", () => {
|
|
156
|
+
const props = {
|
|
157
|
+
name: "test-network-manager",
|
|
158
|
+
location: "eastus",
|
|
159
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
160
|
+
networkManagerScopes: {
|
|
161
|
+
managementGroups: [
|
|
162
|
+
"/providers/Microsoft.Management/managementGroups/mg1",
|
|
163
|
+
"/providers/Microsoft.Management/managementGroups/mg2",
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
167
|
+
};
|
|
168
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
169
|
+
expect(manager.props.networkManagerScopes.managementGroups).toHaveLength(2);
|
|
170
|
+
expect(manager.props.networkManagerScopes.managementGroups).toContain("/providers/Microsoft.Management/managementGroups/mg1");
|
|
171
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
172
|
+
const stackConfig = JSON.parse(synthesized);
|
|
173
|
+
expect(stackConfig.resource).toBeDefined();
|
|
174
|
+
});
|
|
175
|
+
it("should properly format networkManagerScopeAccesses with Connectivity and SecurityAdmin", () => {
|
|
176
|
+
const props = {
|
|
177
|
+
name: "test-network-manager",
|
|
178
|
+
location: "eastus",
|
|
179
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
180
|
+
networkManagerScopes: {
|
|
181
|
+
subscriptions: [
|
|
182
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
186
|
+
};
|
|
187
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
188
|
+
expect(manager.props.networkManagerScopeAccesses).toHaveLength(2);
|
|
189
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("Connectivity");
|
|
190
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("SecurityAdmin");
|
|
191
|
+
});
|
|
192
|
+
it("should properly format networkManagerScopeAccesses with Routing", () => {
|
|
193
|
+
const props = {
|
|
194
|
+
name: "test-network-manager",
|
|
195
|
+
location: "eastus",
|
|
196
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
197
|
+
networkManagerScopes: {
|
|
198
|
+
subscriptions: [
|
|
199
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
networkManagerScopeAccesses: ["Routing"],
|
|
203
|
+
};
|
|
204
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
205
|
+
expect(manager.props.networkManagerScopeAccesses).toHaveLength(1);
|
|
206
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("Routing");
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
describe("Tag Management Tests", () => {
|
|
210
|
+
it("should add tags using addTag method", () => {
|
|
211
|
+
const props = {
|
|
212
|
+
name: "test-network-manager",
|
|
213
|
+
location: "eastus",
|
|
214
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
215
|
+
networkManagerScopes: {
|
|
216
|
+
subscriptions: [
|
|
217
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
221
|
+
tags: {
|
|
222
|
+
environment: "test",
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
226
|
+
manager.addTag("project", "network-infrastructure");
|
|
227
|
+
expect(manager.props.tags.project).toBe("network-infrastructure");
|
|
228
|
+
expect(manager.props.tags.environment).toBe("test");
|
|
229
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
230
|
+
expect(synthesized).toContain("network-infrastructure");
|
|
231
|
+
});
|
|
232
|
+
it("should remove tags using removeTag method", () => {
|
|
233
|
+
const props = {
|
|
234
|
+
name: "test-network-manager",
|
|
235
|
+
location: "eastus",
|
|
236
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
237
|
+
networkManagerScopes: {
|
|
238
|
+
subscriptions: [
|
|
239
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
243
|
+
tags: {
|
|
244
|
+
environment: "test",
|
|
245
|
+
temporary: "true",
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
249
|
+
manager.removeTag("temporary");
|
|
250
|
+
expect(manager.props.tags.temporary).toBeUndefined();
|
|
251
|
+
expect(manager.props.tags.environment).toBe("test");
|
|
252
|
+
});
|
|
253
|
+
it("should add tags when no initial tags exist", () => {
|
|
254
|
+
const props = {
|
|
255
|
+
name: "test-network-manager",
|
|
256
|
+
location: "eastus",
|
|
257
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
258
|
+
networkManagerScopes: {
|
|
259
|
+
subscriptions: [
|
|
260
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
264
|
+
};
|
|
265
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
266
|
+
manager.addTag("firstTag", "firstValue");
|
|
267
|
+
expect(manager.props.tags.firstTag).toBe("firstValue");
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
describe("Terraform Output Tests", () => {
|
|
271
|
+
it("should create proper Terraform outputs", () => {
|
|
272
|
+
const props = {
|
|
273
|
+
name: "test-network-manager",
|
|
274
|
+
location: "eastus",
|
|
275
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
276
|
+
networkManagerScopes: {
|
|
277
|
+
subscriptions: [
|
|
278
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
282
|
+
};
|
|
283
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
284
|
+
expect(manager.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
285
|
+
expect(manager.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
286
|
+
expect(manager.locationOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
287
|
+
expect(manager.tagsOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
288
|
+
expect(manager.scopeOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
289
|
+
expect(manager.scopeAccessesOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
290
|
+
});
|
|
291
|
+
it("should have proper resource references in outputs", () => {
|
|
292
|
+
const props = {
|
|
293
|
+
name: "test-network-manager",
|
|
294
|
+
location: "eastus",
|
|
295
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
296
|
+
networkManagerScopes: {
|
|
297
|
+
subscriptions: [
|
|
298
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
302
|
+
};
|
|
303
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
304
|
+
expect(manager.id).toMatch(/^\$\{.*\.id\}$/);
|
|
305
|
+
expect(manager.resourceName).toMatch(/^\$\{.*\.name\}$/);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
describe("Lifecycle Management Tests", () => {
|
|
309
|
+
it("should apply ignore_changes when specified", () => {
|
|
310
|
+
const props = {
|
|
311
|
+
name: "test-network-manager",
|
|
312
|
+
location: "eastus",
|
|
313
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
314
|
+
networkManagerScopes: {
|
|
315
|
+
subscriptions: [
|
|
316
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
320
|
+
ignoreChanges: ["tags"],
|
|
321
|
+
};
|
|
322
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
323
|
+
expect(manager.props.ignoreChanges).toEqual(["tags"]);
|
|
324
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
325
|
+
const stackConfig = JSON.parse(synthesized);
|
|
326
|
+
expect(stackConfig.resource).toBeDefined();
|
|
327
|
+
});
|
|
328
|
+
it("should handle multiple ignore_changes properties", () => {
|
|
329
|
+
const props = {
|
|
330
|
+
name: "test-network-manager",
|
|
331
|
+
location: "eastus",
|
|
332
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
333
|
+
networkManagerScopes: {
|
|
334
|
+
subscriptions: [
|
|
335
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
336
|
+
],
|
|
337
|
+
},
|
|
338
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
339
|
+
ignoreChanges: ["tags", "description"],
|
|
340
|
+
};
|
|
341
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
342
|
+
expect(manager.props.ignoreChanges).toHaveLength(2);
|
|
343
|
+
expect(manager.props.ignoreChanges).toContain("tags");
|
|
344
|
+
expect(manager.props.ignoreChanges).toContain("description");
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
describe("CDK Synthesis Tests", () => {
|
|
348
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
349
|
+
const props = {
|
|
350
|
+
name: "test-network-manager",
|
|
351
|
+
location: "eastus",
|
|
352
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
353
|
+
networkManagerScopes: {
|
|
354
|
+
subscriptions: [
|
|
355
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
356
|
+
],
|
|
357
|
+
},
|
|
358
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
359
|
+
description: "Test network manager",
|
|
360
|
+
tags: {
|
|
361
|
+
environment: "test",
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
365
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
366
|
+
expect(synthesized).toBeDefined();
|
|
367
|
+
const stackConfig = JSON.parse(synthesized);
|
|
368
|
+
expect(stackConfig.resource).toBeDefined();
|
|
369
|
+
});
|
|
370
|
+
it("should handle multiple Virtual Network Managers in the same stack", () => {
|
|
371
|
+
const props1 = {
|
|
372
|
+
name: "test-network-manager-1",
|
|
373
|
+
location: "eastus",
|
|
374
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
375
|
+
networkManagerScopes: {
|
|
376
|
+
subscriptions: [
|
|
377
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
381
|
+
};
|
|
382
|
+
const props2 = {
|
|
383
|
+
name: "test-network-manager-2",
|
|
384
|
+
location: "westus",
|
|
385
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
386
|
+
apiVersion: "2023-11-01",
|
|
387
|
+
networkManagerScopes: {
|
|
388
|
+
subscriptions: [
|
|
389
|
+
"/subscriptions/11111111-1111-1111-1111-111111111111",
|
|
390
|
+
],
|
|
391
|
+
},
|
|
392
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
393
|
+
};
|
|
394
|
+
const manager1 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager1", props1);
|
|
395
|
+
const manager2 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager2", props2);
|
|
396
|
+
expect(manager1.resolvedApiVersion).toBe("2024-05-01");
|
|
397
|
+
expect(manager2.resolvedApiVersion).toBe("2023-11-01");
|
|
398
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
399
|
+
expect(synthesized).toBeDefined();
|
|
400
|
+
});
|
|
401
|
+
it("should verify Terraform output structure", () => {
|
|
402
|
+
const props = {
|
|
403
|
+
name: "test-network-manager",
|
|
404
|
+
location: "eastus",
|
|
405
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
406
|
+
networkManagerScopes: {
|
|
407
|
+
subscriptions: [
|
|
408
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
412
|
+
};
|
|
413
|
+
new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
414
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
415
|
+
const stackConfig = JSON.parse(synthesized);
|
|
416
|
+
expect(stackConfig.resource).toBeDefined();
|
|
417
|
+
expect(stackConfig.output).toBeDefined();
|
|
418
|
+
expect(stackConfig.output.id).toBeDefined();
|
|
419
|
+
expect(stackConfig.output.name).toBeDefined();
|
|
420
|
+
expect(stackConfig.output.location).toBeDefined();
|
|
421
|
+
expect(stackConfig.output.tags).toBeDefined();
|
|
422
|
+
expect(stackConfig.output.scope).toBeDefined();
|
|
423
|
+
expect(stackConfig.output.scopeAccesses).toBeDefined();
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
describe("Resource Type and Version Tests", () => {
|
|
427
|
+
it("should have correct resource type", () => {
|
|
428
|
+
const props = {
|
|
429
|
+
name: "test-network-manager",
|
|
430
|
+
location: "eastus",
|
|
431
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
432
|
+
networkManagerScopes: {
|
|
433
|
+
subscriptions: [
|
|
434
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
435
|
+
],
|
|
436
|
+
},
|
|
437
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
438
|
+
};
|
|
439
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
440
|
+
expect(manager).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
|
|
441
|
+
});
|
|
442
|
+
it("should support all registered API versions", () => {
|
|
443
|
+
const versions = ["2023-11-01", "2024-05-01"];
|
|
444
|
+
versions.forEach((version) => {
|
|
445
|
+
const testStack = new cdktf.TerraformStack(app, `Stack-${version}`);
|
|
446
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(testStack, `Manager-${version}`, {
|
|
447
|
+
name: `manager-${version}`,
|
|
448
|
+
location: "eastus",
|
|
449
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
450
|
+
apiVersion: version,
|
|
451
|
+
networkManagerScopes: {
|
|
452
|
+
subscriptions: [
|
|
453
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
454
|
+
],
|
|
455
|
+
},
|
|
456
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
457
|
+
});
|
|
458
|
+
expect(manager.resolvedApiVersion).toBe(version);
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
it("should use latest version as default", () => {
|
|
462
|
+
const props = {
|
|
463
|
+
name: "test-network-manager",
|
|
464
|
+
location: "eastus",
|
|
465
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
466
|
+
networkManagerScopes: {
|
|
467
|
+
subscriptions: [
|
|
468
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
469
|
+
],
|
|
470
|
+
},
|
|
471
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
472
|
+
};
|
|
473
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
474
|
+
expect(manager.resolvedApiVersion).toBe("2024-05-01");
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
describe("Description Property Tests", () => {
|
|
478
|
+
it("should create Virtual Network Manager with description", () => {
|
|
479
|
+
const props = {
|
|
480
|
+
name: "test-network-manager",
|
|
481
|
+
location: "eastus",
|
|
482
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
483
|
+
networkManagerScopes: {
|
|
484
|
+
subscriptions: [
|
|
485
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
486
|
+
],
|
|
487
|
+
},
|
|
488
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
489
|
+
description: "Central network management for production workloads",
|
|
490
|
+
};
|
|
491
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
492
|
+
expect(manager.props.description).toBe("Central network management for production workloads");
|
|
493
|
+
});
|
|
494
|
+
it("should create Virtual Network Manager without description", () => {
|
|
495
|
+
const props = {
|
|
496
|
+
name: "test-network-manager",
|
|
497
|
+
location: "eastus",
|
|
498
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
499
|
+
networkManagerScopes: {
|
|
500
|
+
subscriptions: [
|
|
501
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
502
|
+
],
|
|
503
|
+
},
|
|
504
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
505
|
+
};
|
|
506
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
507
|
+
expect(manager.props.description).toBeUndefined();
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
describe("Mixed Scope Configuration Tests", () => {
|
|
511
|
+
it("should support both subscriptions and management groups in scope", () => {
|
|
512
|
+
const props = {
|
|
513
|
+
name: "test-network-manager",
|
|
514
|
+
location: "eastus",
|
|
515
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
516
|
+
networkManagerScopes: {
|
|
517
|
+
subscriptions: [
|
|
518
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
519
|
+
],
|
|
520
|
+
managementGroups: [
|
|
521
|
+
"/providers/Microsoft.Management/managementGroups/mg1",
|
|
522
|
+
],
|
|
523
|
+
},
|
|
524
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
525
|
+
};
|
|
526
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
527
|
+
expect(manager.props.networkManagerScopes.subscriptions).toHaveLength(1);
|
|
528
|
+
expect(manager.props.networkManagerScopes.managementGroups).toHaveLength(1);
|
|
529
|
+
});
|
|
530
|
+
it("should support all three scope access types", () => {
|
|
531
|
+
const props = {
|
|
532
|
+
name: "test-network-manager",
|
|
533
|
+
location: "eastus",
|
|
534
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
535
|
+
networkManagerScopes: {
|
|
536
|
+
subscriptions: [
|
|
537
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
538
|
+
],
|
|
539
|
+
},
|
|
540
|
+
networkManagerScopeAccesses: [
|
|
541
|
+
"Connectivity",
|
|
542
|
+
"SecurityAdmin",
|
|
543
|
+
"Routing",
|
|
544
|
+
],
|
|
545
|
+
};
|
|
546
|
+
const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
|
|
547
|
+
expect(manager.props.networkManagerScopeAccesses).toHaveLength(3);
|
|
548
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("Connectivity");
|
|
549
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("SecurityAdmin");
|
|
550
|
+
expect(manager.props.networkManagerScopeAccesses).toContain("Routing");
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
describe("Convenience Methods for Child Resources", () => {
|
|
554
|
+
let manager;
|
|
555
|
+
beforeEach(() => {
|
|
556
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
557
|
+
name: "test-manager",
|
|
558
|
+
location: "eastus",
|
|
559
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
560
|
+
networkManagerScopes: {
|
|
561
|
+
subscriptions: [
|
|
562
|
+
"/subscriptions/00000000-0000-0000-0000-000000000000",
|
|
563
|
+
],
|
|
564
|
+
},
|
|
565
|
+
networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
it("should create NetworkGroup using convenience method", () => {
|
|
569
|
+
const networkGroup = manager.addNetworkGroup("prod-group", {
|
|
570
|
+
name: "production-vnets",
|
|
571
|
+
description: "Production virtual networks",
|
|
572
|
+
memberType: "VirtualNetwork",
|
|
573
|
+
});
|
|
574
|
+
expect(networkGroup).toBeInstanceOf(network_group_1.NetworkGroup);
|
|
575
|
+
expect(networkGroup.props.networkManagerId).toBe(manager.id);
|
|
576
|
+
expect(networkGroup.props.name).toBe("production-vnets");
|
|
577
|
+
expect(networkGroup.props.description).toBe("Production virtual networks");
|
|
578
|
+
});
|
|
579
|
+
it("should create ConnectivityConfiguration using convenience method", () => {
|
|
580
|
+
const networkGroup = manager.addNetworkGroup("prod-group", {
|
|
581
|
+
name: "production-vnets",
|
|
582
|
+
});
|
|
583
|
+
const connectivityConfig = manager.addConnectivityConfiguration("hub-spoke", {
|
|
584
|
+
name: "production-hub-spoke",
|
|
585
|
+
connectivityTopology: "HubAndSpoke",
|
|
586
|
+
appliesToGroups: [
|
|
587
|
+
{
|
|
588
|
+
networkGroupId: networkGroup.id,
|
|
589
|
+
groupConnectivity: "None",
|
|
590
|
+
useHubGateway: true,
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
hubs: [
|
|
594
|
+
{
|
|
595
|
+
resourceId: "/subscriptions/test/virtualNetworks/hub",
|
|
596
|
+
resourceType: "Microsoft.Network/virtualNetworks",
|
|
597
|
+
},
|
|
598
|
+
],
|
|
599
|
+
});
|
|
600
|
+
expect(connectivityConfig).toBeInstanceOf(connectivity_configuration_1.ConnectivityConfiguration);
|
|
601
|
+
expect(connectivityConfig.props.networkManagerId).toBe(manager.id);
|
|
602
|
+
expect(connectivityConfig.props.connectivityTopology).toBe("HubAndSpoke");
|
|
603
|
+
});
|
|
604
|
+
it("should create SecurityAdminConfiguration using convenience method", () => {
|
|
605
|
+
const securityConfig = manager.addSecurityAdminConfiguration("security", {
|
|
606
|
+
name: "production-security",
|
|
607
|
+
description: "High-priority security rules",
|
|
608
|
+
});
|
|
609
|
+
expect(securityConfig).toBeInstanceOf(security_admin_configuration_1.SecurityAdminConfiguration);
|
|
610
|
+
expect(securityConfig.props.networkManagerId).toBe(manager.id);
|
|
611
|
+
expect(securityConfig.props.name).toBe("production-security");
|
|
612
|
+
});
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
describe("NetworkGroup", () => {
|
|
616
|
+
let app;
|
|
617
|
+
let stack;
|
|
618
|
+
let manager;
|
|
619
|
+
beforeEach(() => {
|
|
620
|
+
app = cdktf_1.Testing.app();
|
|
621
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
622
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
623
|
+
name: "test-manager",
|
|
624
|
+
location: "eastus",
|
|
625
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
626
|
+
networkManagerScopes: {
|
|
627
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
628
|
+
},
|
|
629
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
describe("Basic Instantiation", () => {
|
|
633
|
+
it("should create NetworkGroup with minimum required properties", () => {
|
|
634
|
+
const props = {
|
|
635
|
+
name: "test-group",
|
|
636
|
+
networkManagerId: manager.id,
|
|
637
|
+
};
|
|
638
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", props);
|
|
639
|
+
expect(networkGroup).toBeInstanceOf(network_group_1.NetworkGroup);
|
|
640
|
+
expect(networkGroup.props).toBe(props);
|
|
641
|
+
expect(networkGroup.resourceName).toBeDefined();
|
|
642
|
+
expect(networkGroup.id).toBeDefined();
|
|
643
|
+
});
|
|
644
|
+
it("should create NetworkGroup with all properties", () => {
|
|
645
|
+
const props = {
|
|
646
|
+
name: "production-vnets",
|
|
647
|
+
networkManagerId: manager.id,
|
|
648
|
+
description: "Production virtual networks for East US",
|
|
649
|
+
memberType: "VirtualNetwork",
|
|
650
|
+
};
|
|
651
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", props);
|
|
652
|
+
expect(networkGroup.props.description).toBe("Production virtual networks for East US");
|
|
653
|
+
expect(networkGroup.props.memberType).toBe("VirtualNetwork");
|
|
654
|
+
});
|
|
655
|
+
it("should create NetworkGroup with Subnet member type", () => {
|
|
656
|
+
const props = {
|
|
657
|
+
name: "subnet-group",
|
|
658
|
+
networkManagerId: manager.id,
|
|
659
|
+
memberType: "Subnet",
|
|
660
|
+
description: "Subnet-level network group",
|
|
661
|
+
};
|
|
662
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "SubnetGroup", props);
|
|
663
|
+
expect(networkGroup.props.memberType).toBe("Subnet");
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
describe("API Version Handling", () => {
|
|
667
|
+
it("should use default API version when none specified", () => {
|
|
668
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
669
|
+
name: "test-group",
|
|
670
|
+
networkManagerId: manager.id,
|
|
671
|
+
});
|
|
672
|
+
expect(networkGroup.resolvedApiVersion).toBe("2024-05-01");
|
|
673
|
+
});
|
|
674
|
+
it("should use specified API version when provided", () => {
|
|
675
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
676
|
+
name: "test-group",
|
|
677
|
+
networkManagerId: manager.id,
|
|
678
|
+
apiVersion: "2023-11-01",
|
|
679
|
+
});
|
|
680
|
+
expect(networkGroup.resolvedApiVersion).toBe("2023-11-01");
|
|
681
|
+
});
|
|
682
|
+
});
|
|
683
|
+
describe("Terraform Outputs", () => {
|
|
684
|
+
it("should create proper Terraform outputs", () => {
|
|
685
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
686
|
+
name: "test-group",
|
|
687
|
+
networkManagerId: manager.id,
|
|
688
|
+
});
|
|
689
|
+
expect(networkGroup.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
690
|
+
expect(networkGroup.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
691
|
+
expect(networkGroup.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
692
|
+
});
|
|
693
|
+
it("should have proper resource references", () => {
|
|
694
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
695
|
+
name: "test-group",
|
|
696
|
+
networkManagerId: manager.id,
|
|
697
|
+
});
|
|
698
|
+
expect(networkGroup.id).toMatch(/^\$\{.*\.id\}$/);
|
|
699
|
+
expect(networkGroup.resourceName).toMatch(/^\$\{.*\.name\}$/);
|
|
700
|
+
expect(networkGroup.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
describe("Lifecycle Management", () => {
|
|
704
|
+
it("should apply ignore_changes when specified", () => {
|
|
705
|
+
const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
706
|
+
name: "test-group",
|
|
707
|
+
networkManagerId: manager.id,
|
|
708
|
+
ignoreChanges: ["description"],
|
|
709
|
+
});
|
|
710
|
+
expect(networkGroup.props.ignoreChanges).toEqual(["description"]);
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
describe("CDK Synthesis", () => {
|
|
714
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
715
|
+
new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
716
|
+
name: "test-group",
|
|
717
|
+
networkManagerId: manager.id,
|
|
718
|
+
description: "Test network group",
|
|
719
|
+
});
|
|
720
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
721
|
+
expect(synthesized).toBeDefined();
|
|
722
|
+
const stackConfig = JSON.parse(synthesized);
|
|
723
|
+
expect(stackConfig.resource).toBeDefined();
|
|
724
|
+
});
|
|
725
|
+
});
|
|
726
|
+
});
|
|
727
|
+
describe("NetworkGroupStaticMember", () => {
|
|
728
|
+
let app;
|
|
729
|
+
let stack;
|
|
730
|
+
let manager;
|
|
731
|
+
let networkGroup;
|
|
732
|
+
beforeEach(() => {
|
|
733
|
+
app = cdktf_1.Testing.app();
|
|
734
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
735
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
736
|
+
name: "test-manager",
|
|
737
|
+
location: "eastus",
|
|
738
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
739
|
+
networkManagerScopes: {
|
|
740
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
741
|
+
},
|
|
742
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
743
|
+
});
|
|
744
|
+
networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
745
|
+
name: "test-group",
|
|
746
|
+
networkManagerId: manager.id,
|
|
747
|
+
});
|
|
748
|
+
});
|
|
749
|
+
describe("Basic Instantiation", () => {
|
|
750
|
+
it("should create StaticMember for VNet", () => {
|
|
751
|
+
const props = {
|
|
752
|
+
name: "vnet-member",
|
|
753
|
+
networkGroupId: networkGroup.id,
|
|
754
|
+
resourceId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet",
|
|
755
|
+
};
|
|
756
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "VnetMember", props);
|
|
757
|
+
expect(member).toBeInstanceOf(network_group_static_member_1.NetworkGroupStaticMember);
|
|
758
|
+
expect(member.props).toBe(props);
|
|
759
|
+
expect(member.props.resourceId).toContain("virtualNetworks");
|
|
760
|
+
});
|
|
761
|
+
it("should create StaticMember for Subnet", () => {
|
|
762
|
+
const props = {
|
|
763
|
+
name: "subnet-member",
|
|
764
|
+
networkGroupId: networkGroup.id,
|
|
765
|
+
resourceId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet",
|
|
766
|
+
};
|
|
767
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "SubnetMember", props);
|
|
768
|
+
expect(member).toBeInstanceOf(network_group_static_member_1.NetworkGroupStaticMember);
|
|
769
|
+
expect(member.props.resourceId).toContain("subnets");
|
|
770
|
+
});
|
|
771
|
+
});
|
|
772
|
+
describe("API Version Handling", () => {
|
|
773
|
+
it("should use default API version when none specified", () => {
|
|
774
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
775
|
+
name: "test-member",
|
|
776
|
+
networkGroupId: networkGroup.id,
|
|
777
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
778
|
+
});
|
|
779
|
+
expect(member.resolvedApiVersion).toBe("2024-05-01");
|
|
780
|
+
});
|
|
781
|
+
it("should use specified API version when provided", () => {
|
|
782
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
783
|
+
name: "test-member",
|
|
784
|
+
networkGroupId: networkGroup.id,
|
|
785
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
786
|
+
apiVersion: "2023-11-01",
|
|
787
|
+
});
|
|
788
|
+
expect(member.resolvedApiVersion).toBe("2023-11-01");
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
describe("Terraform Outputs", () => {
|
|
792
|
+
it("should create proper Terraform outputs", () => {
|
|
793
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
794
|
+
name: "test-member",
|
|
795
|
+
networkGroupId: networkGroup.id,
|
|
796
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
797
|
+
});
|
|
798
|
+
expect(member.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
799
|
+
expect(member.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
800
|
+
expect(member.resourceIdOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
801
|
+
});
|
|
802
|
+
it("should have proper resource references", () => {
|
|
803
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
804
|
+
name: "test-member",
|
|
805
|
+
networkGroupId: networkGroup.id,
|
|
806
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
807
|
+
});
|
|
808
|
+
expect(member.id).toMatch(/^\$\{.*\.id\}$/);
|
|
809
|
+
expect(member.resourceName).toMatch(/^\$\{.*\.name\}$/);
|
|
810
|
+
// memberResourceId returns the input resourceId since Azure API doesn't return it
|
|
811
|
+
expect(member.memberResourceId).toBe("/subscriptions/test/virtualNetworks/vnet1");
|
|
812
|
+
expect(member.region).toMatch(/^\$\{.*\.output\.properties\.region\}$/);
|
|
813
|
+
});
|
|
814
|
+
});
|
|
815
|
+
describe("Parent-Child Relationship", () => {
|
|
816
|
+
it("should correctly reference parent network group", () => {
|
|
817
|
+
const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
818
|
+
name: "test-member",
|
|
819
|
+
networkGroupId: networkGroup.id,
|
|
820
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
821
|
+
});
|
|
822
|
+
expect(member.props.networkGroupId).toBe(networkGroup.id);
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
describe("CDK Synthesis", () => {
|
|
826
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
827
|
+
new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
|
|
828
|
+
name: "test-member",
|
|
829
|
+
networkGroupId: networkGroup.id,
|
|
830
|
+
resourceId: "/subscriptions/test/virtualNetworks/vnet1",
|
|
831
|
+
});
|
|
832
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
833
|
+
expect(synthesized).toBeDefined();
|
|
834
|
+
const stackConfig = JSON.parse(synthesized);
|
|
835
|
+
expect(stackConfig.resource).toBeDefined();
|
|
836
|
+
});
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
describe("ConnectivityConfiguration", () => {
|
|
840
|
+
let app;
|
|
841
|
+
let stack;
|
|
842
|
+
let manager;
|
|
843
|
+
let networkGroup;
|
|
844
|
+
beforeEach(() => {
|
|
845
|
+
app = cdktf_1.Testing.app();
|
|
846
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
847
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
848
|
+
name: "test-manager",
|
|
849
|
+
location: "eastus",
|
|
850
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
851
|
+
networkManagerScopes: {
|
|
852
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
853
|
+
},
|
|
854
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
855
|
+
});
|
|
856
|
+
networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
857
|
+
name: "test-group",
|
|
858
|
+
networkManagerId: manager.id,
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
describe("Basic Instantiation - Mesh Topology", () => {
|
|
862
|
+
it("should create Mesh connectivity configuration", () => {
|
|
863
|
+
const props = {
|
|
864
|
+
name: "mesh-config",
|
|
865
|
+
networkManagerId: manager.id,
|
|
866
|
+
connectivityTopology: "Mesh",
|
|
867
|
+
appliesToGroups: [
|
|
868
|
+
{
|
|
869
|
+
networkGroupId: networkGroup.id,
|
|
870
|
+
groupConnectivity: "DirectlyConnected",
|
|
871
|
+
isGlobal: false,
|
|
872
|
+
},
|
|
873
|
+
],
|
|
874
|
+
};
|
|
875
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "MeshConfig", props);
|
|
876
|
+
expect(config).toBeInstanceOf(connectivity_configuration_1.ConnectivityConfiguration);
|
|
877
|
+
expect(config.topology).toBe("Mesh");
|
|
878
|
+
expect(config.props.appliesToGroups).toHaveLength(1);
|
|
879
|
+
});
|
|
880
|
+
it("should create global Mesh connectivity configuration", () => {
|
|
881
|
+
const props = {
|
|
882
|
+
name: "global-mesh",
|
|
883
|
+
networkManagerId: manager.id,
|
|
884
|
+
connectivityTopology: "Mesh",
|
|
885
|
+
appliesToGroups: [
|
|
886
|
+
{
|
|
887
|
+
networkGroupId: networkGroup.id,
|
|
888
|
+
groupConnectivity: "DirectlyConnected",
|
|
889
|
+
isGlobal: true,
|
|
890
|
+
},
|
|
891
|
+
],
|
|
892
|
+
isGlobal: true,
|
|
893
|
+
};
|
|
894
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "GlobalMesh", props);
|
|
895
|
+
expect(config.props.isGlobal).toBe(true);
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
describe("Basic Instantiation - Hub-and-Spoke Topology", () => {
|
|
899
|
+
it("should create Hub-and-Spoke connectivity configuration", () => {
|
|
900
|
+
const props = {
|
|
901
|
+
name: "hub-spoke-config",
|
|
902
|
+
networkManagerId: manager.id,
|
|
903
|
+
connectivityTopology: "HubAndSpoke",
|
|
904
|
+
appliesToGroups: [
|
|
905
|
+
{
|
|
906
|
+
networkGroupId: networkGroup.id,
|
|
907
|
+
groupConnectivity: "None",
|
|
908
|
+
useHubGateway: true,
|
|
909
|
+
},
|
|
910
|
+
],
|
|
911
|
+
hubs: [
|
|
912
|
+
{
|
|
913
|
+
resourceId: "/subscriptions/test/virtualNetworks/hub-vnet",
|
|
914
|
+
resourceType: "Microsoft.Network/virtualNetworks",
|
|
915
|
+
},
|
|
916
|
+
],
|
|
917
|
+
};
|
|
918
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "HubSpokeConfig", props);
|
|
919
|
+
expect(config.topology).toBe("HubAndSpoke");
|
|
920
|
+
expect(config.props.hubs).toHaveLength(1);
|
|
921
|
+
expect(config.props.appliesToGroups[0].useHubGateway).toBe(true);
|
|
922
|
+
});
|
|
923
|
+
it("should create Hub-and-Spoke with multiple hubs", () => {
|
|
924
|
+
const props = {
|
|
925
|
+
name: "multi-hub-config",
|
|
926
|
+
networkManagerId: manager.id,
|
|
927
|
+
connectivityTopology: "HubAndSpoke",
|
|
928
|
+
appliesToGroups: [
|
|
929
|
+
{
|
|
930
|
+
networkGroupId: networkGroup.id,
|
|
931
|
+
groupConnectivity: "None",
|
|
932
|
+
},
|
|
933
|
+
],
|
|
934
|
+
hubs: [
|
|
935
|
+
{
|
|
936
|
+
resourceId: "/subscriptions/test/virtualNetworks/hub-vnet-1",
|
|
937
|
+
resourceType: "Microsoft.Network/virtualNetworks",
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
resourceId: "/subscriptions/test/virtualNetworks/hub-vnet-2",
|
|
941
|
+
resourceType: "Microsoft.Network/virtualNetworks",
|
|
942
|
+
},
|
|
943
|
+
],
|
|
944
|
+
};
|
|
945
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "MultiHubConfig", props);
|
|
946
|
+
expect(config.props.hubs).toHaveLength(2);
|
|
947
|
+
});
|
|
948
|
+
});
|
|
949
|
+
describe("Property Validation", () => {
|
|
950
|
+
it("should handle description property", () => {
|
|
951
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
952
|
+
name: "test-config",
|
|
953
|
+
networkManagerId: manager.id,
|
|
954
|
+
description: "Hub-and-spoke topology for production workloads",
|
|
955
|
+
connectivityTopology: "HubAndSpoke",
|
|
956
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
957
|
+
hubs: [
|
|
958
|
+
{
|
|
959
|
+
resourceId: "/subscriptions/test/virtualNetworks/hub",
|
|
960
|
+
resourceType: "Microsoft.Network/virtualNetworks",
|
|
961
|
+
},
|
|
962
|
+
],
|
|
963
|
+
});
|
|
964
|
+
expect(config.props.description).toBe("Hub-and-spoke topology for production workloads");
|
|
965
|
+
});
|
|
966
|
+
it("should handle deleteExistingPeering property", () => {
|
|
967
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
968
|
+
name: "test-config",
|
|
969
|
+
networkManagerId: manager.id,
|
|
970
|
+
connectivityTopology: "Mesh",
|
|
971
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
972
|
+
deleteExistingPeering: true,
|
|
973
|
+
});
|
|
974
|
+
expect(config.props.deleteExistingPeering).toBe(true);
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
describe("API Version Handling", () => {
|
|
978
|
+
it("should use default API version when none specified", () => {
|
|
979
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
980
|
+
name: "test-config",
|
|
981
|
+
networkManagerId: manager.id,
|
|
982
|
+
connectivityTopology: "Mesh",
|
|
983
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
984
|
+
});
|
|
985
|
+
expect(config.resolvedApiVersion).toBe("2024-05-01");
|
|
986
|
+
});
|
|
987
|
+
it("should use specified API version when provided", () => {
|
|
988
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
989
|
+
name: "test-config",
|
|
990
|
+
networkManagerId: manager.id,
|
|
991
|
+
apiVersion: "2023-11-01",
|
|
992
|
+
connectivityTopology: "Mesh",
|
|
993
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
994
|
+
});
|
|
995
|
+
expect(config.resolvedApiVersion).toBe("2023-11-01");
|
|
996
|
+
});
|
|
997
|
+
});
|
|
998
|
+
describe("Terraform Outputs", () => {
|
|
999
|
+
it("should create proper Terraform outputs", () => {
|
|
1000
|
+
const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
1001
|
+
name: "test-config",
|
|
1002
|
+
networkManagerId: manager.id,
|
|
1003
|
+
connectivityTopology: "Mesh",
|
|
1004
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1005
|
+
});
|
|
1006
|
+
expect(config.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1007
|
+
expect(config.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1008
|
+
expect(config.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1009
|
+
});
|
|
1010
|
+
});
|
|
1011
|
+
describe("CDK Synthesis", () => {
|
|
1012
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
1013
|
+
new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
|
|
1014
|
+
name: "test-config",
|
|
1015
|
+
networkManagerId: manager.id,
|
|
1016
|
+
connectivityTopology: "Mesh",
|
|
1017
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1018
|
+
});
|
|
1019
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
1020
|
+
expect(synthesized).toBeDefined();
|
|
1021
|
+
const stackConfig = JSON.parse(synthesized);
|
|
1022
|
+
expect(stackConfig.resource).toBeDefined();
|
|
1023
|
+
});
|
|
1024
|
+
});
|
|
1025
|
+
});
|
|
1026
|
+
describe("SecurityAdminConfiguration", () => {
|
|
1027
|
+
let app;
|
|
1028
|
+
let stack;
|
|
1029
|
+
let manager;
|
|
1030
|
+
beforeEach(() => {
|
|
1031
|
+
app = cdktf_1.Testing.app();
|
|
1032
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
1033
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
1034
|
+
name: "test-manager",
|
|
1035
|
+
location: "eastus",
|
|
1036
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
1037
|
+
networkManagerScopes: {
|
|
1038
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
1039
|
+
},
|
|
1040
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
1041
|
+
});
|
|
1042
|
+
});
|
|
1043
|
+
describe("Basic Instantiation", () => {
|
|
1044
|
+
it("should create SecurityAdminConfiguration with minimum properties", () => {
|
|
1045
|
+
const props = {
|
|
1046
|
+
name: "security-config",
|
|
1047
|
+
networkManagerId: manager.id,
|
|
1048
|
+
};
|
|
1049
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", props);
|
|
1050
|
+
expect(config).toBeInstanceOf(security_admin_configuration_1.SecurityAdminConfiguration);
|
|
1051
|
+
expect(config.props).toBe(props);
|
|
1052
|
+
});
|
|
1053
|
+
it("should create SecurityAdminConfiguration with all properties", () => {
|
|
1054
|
+
const props = {
|
|
1055
|
+
name: "security-config",
|
|
1056
|
+
networkManagerId: manager.id,
|
|
1057
|
+
description: "Organization-wide security rules",
|
|
1058
|
+
applyOnNetworkIntentPolicyBasedServices: ["None"],
|
|
1059
|
+
};
|
|
1060
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", props);
|
|
1061
|
+
expect(config.props.description).toBe("Organization-wide security rules");
|
|
1062
|
+
expect(config.props.applyOnNetworkIntentPolicyBasedServices).toEqual([
|
|
1063
|
+
"None",
|
|
1064
|
+
]);
|
|
1065
|
+
});
|
|
1066
|
+
});
|
|
1067
|
+
describe("API Version Handling", () => {
|
|
1068
|
+
it("should use default API version when none specified", () => {
|
|
1069
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1070
|
+
name: "security-config",
|
|
1071
|
+
networkManagerId: manager.id,
|
|
1072
|
+
});
|
|
1073
|
+
expect(config.resolvedApiVersion).toBe("2024-05-01");
|
|
1074
|
+
});
|
|
1075
|
+
it("should use specified API version when provided", () => {
|
|
1076
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1077
|
+
name: "security-config",
|
|
1078
|
+
networkManagerId: manager.id,
|
|
1079
|
+
apiVersion: "2023-11-01",
|
|
1080
|
+
});
|
|
1081
|
+
expect(config.resolvedApiVersion).toBe("2023-11-01");
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
1084
|
+
describe("Terraform Outputs", () => {
|
|
1085
|
+
it("should create proper Terraform outputs", () => {
|
|
1086
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1087
|
+
name: "security-config",
|
|
1088
|
+
networkManagerId: manager.id,
|
|
1089
|
+
});
|
|
1090
|
+
expect(config.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1091
|
+
expect(config.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1092
|
+
expect(config.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1093
|
+
});
|
|
1094
|
+
it("should have proper resource references", () => {
|
|
1095
|
+
const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1096
|
+
name: "security-config",
|
|
1097
|
+
networkManagerId: manager.id,
|
|
1098
|
+
});
|
|
1099
|
+
expect(config.id).toMatch(/^\$\{.*\.id\}$/);
|
|
1100
|
+
expect(config.resourceName).toMatch(/^\$\{.*\.name\}$/);
|
|
1101
|
+
expect(config.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
|
|
1102
|
+
});
|
|
1103
|
+
});
|
|
1104
|
+
describe("CDK Synthesis", () => {
|
|
1105
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
1106
|
+
new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1107
|
+
name: "security-config",
|
|
1108
|
+
networkManagerId: manager.id,
|
|
1109
|
+
description: "Test security configuration",
|
|
1110
|
+
});
|
|
1111
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
1112
|
+
expect(synthesized).toBeDefined();
|
|
1113
|
+
const stackConfig = JSON.parse(synthesized);
|
|
1114
|
+
expect(stackConfig.resource).toBeDefined();
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
});
|
|
1118
|
+
describe("SecurityAdminRuleCollection", () => {
|
|
1119
|
+
let app;
|
|
1120
|
+
let stack;
|
|
1121
|
+
let manager;
|
|
1122
|
+
let securityConfig;
|
|
1123
|
+
let networkGroup;
|
|
1124
|
+
beforeEach(() => {
|
|
1125
|
+
app = cdktf_1.Testing.app();
|
|
1126
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
1127
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
1128
|
+
name: "test-manager",
|
|
1129
|
+
location: "eastus",
|
|
1130
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
1131
|
+
networkManagerScopes: {
|
|
1132
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
1133
|
+
},
|
|
1134
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
1135
|
+
});
|
|
1136
|
+
securityConfig = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1137
|
+
name: "security-config",
|
|
1138
|
+
networkManagerId: manager.id,
|
|
1139
|
+
});
|
|
1140
|
+
networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
1141
|
+
name: "test-group",
|
|
1142
|
+
networkManagerId: manager.id,
|
|
1143
|
+
});
|
|
1144
|
+
});
|
|
1145
|
+
describe("Basic Instantiation", () => {
|
|
1146
|
+
it("should create RuleCollection with minimum properties", () => {
|
|
1147
|
+
const props = {
|
|
1148
|
+
name: "rule-collection",
|
|
1149
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1150
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1151
|
+
};
|
|
1152
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
|
|
1153
|
+
expect(collection).toBeInstanceOf(security_admin_rule_collection_1.SecurityAdminRuleCollection);
|
|
1154
|
+
expect(collection.props.appliesToGroups).toHaveLength(1);
|
|
1155
|
+
});
|
|
1156
|
+
it("should create RuleCollection with description", () => {
|
|
1157
|
+
const props = {
|
|
1158
|
+
name: "block-high-risk-ports",
|
|
1159
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1160
|
+
description: "Rules to block high-risk ports",
|
|
1161
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1162
|
+
};
|
|
1163
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
|
|
1164
|
+
expect(collection.props.description).toBe("Rules to block high-risk ports");
|
|
1165
|
+
});
|
|
1166
|
+
it("should create RuleCollection applied to multiple groups", () => {
|
|
1167
|
+
const group2 = new network_group_1.NetworkGroup(stack, "TestGroup2", {
|
|
1168
|
+
name: "test-group-2",
|
|
1169
|
+
networkManagerId: manager.id,
|
|
1170
|
+
});
|
|
1171
|
+
const props = {
|
|
1172
|
+
name: "multi-group-collection",
|
|
1173
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1174
|
+
appliesToGroups: [
|
|
1175
|
+
{ networkGroupId: networkGroup.id },
|
|
1176
|
+
{ networkGroupId: group2.id },
|
|
1177
|
+
],
|
|
1178
|
+
};
|
|
1179
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
|
|
1180
|
+
expect(collection.props.appliesToGroups).toHaveLength(2);
|
|
1181
|
+
});
|
|
1182
|
+
});
|
|
1183
|
+
describe("API Version Handling", () => {
|
|
1184
|
+
it("should use default API version when none specified", () => {
|
|
1185
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1186
|
+
name: "rule-collection",
|
|
1187
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1188
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1189
|
+
});
|
|
1190
|
+
expect(collection.resolvedApiVersion).toBe("2024-05-01");
|
|
1191
|
+
});
|
|
1192
|
+
it("should use specified API version when provided", () => {
|
|
1193
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1194
|
+
name: "rule-collection",
|
|
1195
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1196
|
+
apiVersion: "2023-11-01",
|
|
1197
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1198
|
+
});
|
|
1199
|
+
expect(collection.resolvedApiVersion).toBe("2023-11-01");
|
|
1200
|
+
});
|
|
1201
|
+
});
|
|
1202
|
+
describe("Terraform Outputs", () => {
|
|
1203
|
+
it("should create proper Terraform outputs", () => {
|
|
1204
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1205
|
+
name: "rule-collection",
|
|
1206
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1207
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1208
|
+
});
|
|
1209
|
+
expect(collection.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1210
|
+
expect(collection.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1211
|
+
expect(collection.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1212
|
+
});
|
|
1213
|
+
});
|
|
1214
|
+
describe("Parent-Child Relationship", () => {
|
|
1215
|
+
it("should correctly reference parent security admin configuration", () => {
|
|
1216
|
+
const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1217
|
+
name: "rule-collection",
|
|
1218
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1219
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1220
|
+
});
|
|
1221
|
+
expect(collection.props.securityAdminConfigurationId).toBe(securityConfig.id);
|
|
1222
|
+
});
|
|
1223
|
+
});
|
|
1224
|
+
describe("CDK Synthesis", () => {
|
|
1225
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
1226
|
+
new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1227
|
+
name: "rule-collection",
|
|
1228
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1229
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1230
|
+
});
|
|
1231
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
1232
|
+
expect(synthesized).toBeDefined();
|
|
1233
|
+
const stackConfig = JSON.parse(synthesized);
|
|
1234
|
+
expect(stackConfig.resource).toBeDefined();
|
|
1235
|
+
});
|
|
1236
|
+
});
|
|
1237
|
+
});
|
|
1238
|
+
describe("SecurityAdminRule", () => {
|
|
1239
|
+
let app;
|
|
1240
|
+
let stack;
|
|
1241
|
+
let manager;
|
|
1242
|
+
let securityConfig;
|
|
1243
|
+
let networkGroup;
|
|
1244
|
+
let ruleCollection;
|
|
1245
|
+
beforeEach(() => {
|
|
1246
|
+
app = cdktf_1.Testing.app();
|
|
1247
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
1248
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
1249
|
+
name: "test-manager",
|
|
1250
|
+
location: "eastus",
|
|
1251
|
+
resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
|
|
1252
|
+
networkManagerScopes: {
|
|
1253
|
+
subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
|
|
1254
|
+
},
|
|
1255
|
+
networkManagerScopeAccesses: ["SecurityAdmin"],
|
|
1256
|
+
});
|
|
1257
|
+
securityConfig = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
|
|
1258
|
+
name: "security-config",
|
|
1259
|
+
networkManagerId: manager.id,
|
|
1260
|
+
});
|
|
1261
|
+
networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
|
|
1262
|
+
name: "test-group",
|
|
1263
|
+
networkManagerId: manager.id,
|
|
1264
|
+
});
|
|
1265
|
+
ruleCollection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
|
|
1266
|
+
name: "rule-collection",
|
|
1267
|
+
securityAdminConfigurationId: securityConfig.id,
|
|
1268
|
+
appliesToGroups: [{ networkGroupId: networkGroup.id }],
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1271
|
+
describe("Basic Instantiation - Deny Rules", () => {
|
|
1272
|
+
it("should create Deny rule blocking SSH", () => {
|
|
1273
|
+
const props = {
|
|
1274
|
+
name: "block-ssh",
|
|
1275
|
+
ruleCollectionId: ruleCollection.id,
|
|
1276
|
+
description: "Block SSH access from internet",
|
|
1277
|
+
priority: 100,
|
|
1278
|
+
action: "Deny",
|
|
1279
|
+
direction: "Inbound",
|
|
1280
|
+
protocol: "Tcp",
|
|
1281
|
+
destinationPortRanges: ["22"],
|
|
1282
|
+
sources: [
|
|
1283
|
+
{ addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
|
|
1284
|
+
],
|
|
1285
|
+
destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
|
|
1286
|
+
};
|
|
1287
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "BlockSSH", props);
|
|
1288
|
+
expect(rule).toBeInstanceOf(security_admin_rule_1.SecurityAdminRule);
|
|
1289
|
+
expect(rule.ruleAction).toBe("Deny");
|
|
1290
|
+
expect(rule.rulePriority).toBe(100);
|
|
1291
|
+
expect(rule.props.protocol).toBe("Tcp");
|
|
1292
|
+
expect(rule.props.destinationPortRanges).toEqual(["22"]);
|
|
1293
|
+
});
|
|
1294
|
+
it("should create Deny rule blocking RDP", () => {
|
|
1295
|
+
const props = {
|
|
1296
|
+
name: "block-rdp",
|
|
1297
|
+
ruleCollectionId: ruleCollection.id,
|
|
1298
|
+
priority: 101,
|
|
1299
|
+
action: "Deny",
|
|
1300
|
+
direction: "Inbound",
|
|
1301
|
+
protocol: "Tcp",
|
|
1302
|
+
destinationPortRanges: ["3389"],
|
|
1303
|
+
sources: [
|
|
1304
|
+
{ addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
|
|
1305
|
+
],
|
|
1306
|
+
destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
|
|
1307
|
+
};
|
|
1308
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "BlockRDP", props);
|
|
1309
|
+
expect(rule.props.destinationPortRanges).toEqual(["3389"]);
|
|
1310
|
+
});
|
|
1311
|
+
});
|
|
1312
|
+
describe("Basic Instantiation - Allow Rules", () => {
|
|
1313
|
+
it("should create Allow rule", () => {
|
|
1314
|
+
const props = {
|
|
1315
|
+
name: "allow-https",
|
|
1316
|
+
ruleCollectionId: ruleCollection.id,
|
|
1317
|
+
priority: 200,
|
|
1318
|
+
action: "Allow",
|
|
1319
|
+
direction: "Inbound",
|
|
1320
|
+
protocol: "Tcp",
|
|
1321
|
+
destinationPortRanges: ["443"],
|
|
1322
|
+
};
|
|
1323
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AllowHTTPS", props);
|
|
1324
|
+
expect(rule.ruleAction).toBe("Allow");
|
|
1325
|
+
});
|
|
1326
|
+
});
|
|
1327
|
+
describe("Basic Instantiation - AlwaysAllow Rules", () => {
|
|
1328
|
+
it("should create AlwaysAllow rule for monitoring", () => {
|
|
1329
|
+
const props = {
|
|
1330
|
+
name: "always-allow-monitoring",
|
|
1331
|
+
ruleCollectionId: ruleCollection.id,
|
|
1332
|
+
description: "Always allow traffic from monitoring systems",
|
|
1333
|
+
priority: 50,
|
|
1334
|
+
action: "AlwaysAllow",
|
|
1335
|
+
direction: "Inbound",
|
|
1336
|
+
protocol: "Any",
|
|
1337
|
+
sources: [
|
|
1338
|
+
{ addressPrefix: "10.0.0.0/24", addressPrefixType: "IPPrefix" },
|
|
1339
|
+
],
|
|
1340
|
+
destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
|
|
1341
|
+
};
|
|
1342
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AllowMonitoring", props);
|
|
1343
|
+
expect(rule.ruleAction).toBe("AlwaysAllow");
|
|
1344
|
+
expect(rule.rulePriority).toBe(50);
|
|
1345
|
+
});
|
|
1346
|
+
});
|
|
1347
|
+
describe("Protocol Handling", () => {
|
|
1348
|
+
it("should support Tcp protocol", () => {
|
|
1349
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TcpRule", {
|
|
1350
|
+
name: "tcp-rule",
|
|
1351
|
+
ruleCollectionId: ruleCollection.id,
|
|
1352
|
+
priority: 100,
|
|
1353
|
+
action: "Deny",
|
|
1354
|
+
direction: "Inbound",
|
|
1355
|
+
protocol: "Tcp",
|
|
1356
|
+
});
|
|
1357
|
+
expect(rule.props.protocol).toBe("Tcp");
|
|
1358
|
+
});
|
|
1359
|
+
it("should support Udp protocol", () => {
|
|
1360
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "UdpRule", {
|
|
1361
|
+
name: "udp-rule",
|
|
1362
|
+
ruleCollectionId: ruleCollection.id,
|
|
1363
|
+
priority: 100,
|
|
1364
|
+
action: "Deny",
|
|
1365
|
+
direction: "Inbound",
|
|
1366
|
+
protocol: "Udp",
|
|
1367
|
+
});
|
|
1368
|
+
expect(rule.props.protocol).toBe("Udp");
|
|
1369
|
+
});
|
|
1370
|
+
it("should support Icmp protocol", () => {
|
|
1371
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "IcmpRule", {
|
|
1372
|
+
name: "icmp-rule",
|
|
1373
|
+
ruleCollectionId: ruleCollection.id,
|
|
1374
|
+
priority: 100,
|
|
1375
|
+
action: "Deny",
|
|
1376
|
+
direction: "Inbound",
|
|
1377
|
+
protocol: "Icmp",
|
|
1378
|
+
});
|
|
1379
|
+
expect(rule.props.protocol).toBe("Icmp");
|
|
1380
|
+
});
|
|
1381
|
+
it("should support Any protocol", () => {
|
|
1382
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AnyRule", {
|
|
1383
|
+
name: "any-rule",
|
|
1384
|
+
ruleCollectionId: ruleCollection.id,
|
|
1385
|
+
priority: 100,
|
|
1386
|
+
action: "Allow",
|
|
1387
|
+
direction: "Inbound",
|
|
1388
|
+
protocol: "Any",
|
|
1389
|
+
});
|
|
1390
|
+
expect(rule.props.protocol).toBe("Any");
|
|
1391
|
+
});
|
|
1392
|
+
});
|
|
1393
|
+
describe("Direction Handling", () => {
|
|
1394
|
+
it("should support Inbound direction", () => {
|
|
1395
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "InboundRule", {
|
|
1396
|
+
name: "inbound-rule",
|
|
1397
|
+
ruleCollectionId: ruleCollection.id,
|
|
1398
|
+
priority: 100,
|
|
1399
|
+
action: "Deny",
|
|
1400
|
+
direction: "Inbound",
|
|
1401
|
+
protocol: "Tcp",
|
|
1402
|
+
});
|
|
1403
|
+
expect(rule.props.direction).toBe("Inbound");
|
|
1404
|
+
});
|
|
1405
|
+
it("should support Outbound direction", () => {
|
|
1406
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "OutboundRule", {
|
|
1407
|
+
name: "outbound-rule",
|
|
1408
|
+
ruleCollectionId: ruleCollection.id,
|
|
1409
|
+
priority: 100,
|
|
1410
|
+
action: "Deny",
|
|
1411
|
+
direction: "Outbound",
|
|
1412
|
+
protocol: "Tcp",
|
|
1413
|
+
});
|
|
1414
|
+
expect(rule.props.direction).toBe("Outbound");
|
|
1415
|
+
});
|
|
1416
|
+
});
|
|
1417
|
+
describe("Port Range Handling", () => {
|
|
1418
|
+
it("should handle single source port", () => {
|
|
1419
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "SinglePort", {
|
|
1420
|
+
name: "single-port",
|
|
1421
|
+
ruleCollectionId: ruleCollection.id,
|
|
1422
|
+
priority: 100,
|
|
1423
|
+
action: "Deny",
|
|
1424
|
+
direction: "Inbound",
|
|
1425
|
+
protocol: "Tcp",
|
|
1426
|
+
sourcePortRanges: ["80"],
|
|
1427
|
+
});
|
|
1428
|
+
expect(rule.props.sourcePortRanges).toEqual(["80"]);
|
|
1429
|
+
});
|
|
1430
|
+
it("should handle multiple destination ports", () => {
|
|
1431
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "MultiplePorts", {
|
|
1432
|
+
name: "multiple-ports",
|
|
1433
|
+
ruleCollectionId: ruleCollection.id,
|
|
1434
|
+
priority: 100,
|
|
1435
|
+
action: "Deny",
|
|
1436
|
+
direction: "Inbound",
|
|
1437
|
+
protocol: "Tcp",
|
|
1438
|
+
destinationPortRanges: ["80", "443", "8080"],
|
|
1439
|
+
});
|
|
1440
|
+
expect(rule.props.destinationPortRanges).toEqual(["80", "443", "8080"]);
|
|
1441
|
+
});
|
|
1442
|
+
it("should handle port ranges", () => {
|
|
1443
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "PortRange", {
|
|
1444
|
+
name: "port-range",
|
|
1445
|
+
ruleCollectionId: ruleCollection.id,
|
|
1446
|
+
priority: 100,
|
|
1447
|
+
action: "Deny",
|
|
1448
|
+
direction: "Inbound",
|
|
1449
|
+
protocol: "Tcp",
|
|
1450
|
+
destinationPortRanges: ["8000-8999"],
|
|
1451
|
+
});
|
|
1452
|
+
expect(rule.props.destinationPortRanges).toEqual(["8000-8999"]);
|
|
1453
|
+
});
|
|
1454
|
+
it("should default to wildcard when ports not specified", () => {
|
|
1455
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "DefaultPorts", {
|
|
1456
|
+
name: "default-ports",
|
|
1457
|
+
ruleCollectionId: ruleCollection.id,
|
|
1458
|
+
priority: 100,
|
|
1459
|
+
action: "Deny",
|
|
1460
|
+
direction: "Inbound",
|
|
1461
|
+
protocol: "Any",
|
|
1462
|
+
});
|
|
1463
|
+
expect(rule.props.sourcePortRanges).toBeUndefined();
|
|
1464
|
+
expect(rule.props.destinationPortRanges).toBeUndefined();
|
|
1465
|
+
});
|
|
1466
|
+
});
|
|
1467
|
+
describe("Address Prefix Handling", () => {
|
|
1468
|
+
it("should handle IP prefix sources", () => {
|
|
1469
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "IPPrefix", {
|
|
1470
|
+
name: "ip-prefix",
|
|
1471
|
+
ruleCollectionId: ruleCollection.id,
|
|
1472
|
+
priority: 100,
|
|
1473
|
+
action: "Deny",
|
|
1474
|
+
direction: "Inbound",
|
|
1475
|
+
protocol: "Tcp",
|
|
1476
|
+
sources: [
|
|
1477
|
+
{ addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
|
|
1478
|
+
],
|
|
1479
|
+
});
|
|
1480
|
+
expect(rule.props.sources).toEqual([
|
|
1481
|
+
{ addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
|
|
1482
|
+
]);
|
|
1483
|
+
});
|
|
1484
|
+
it("should handle ServiceTag sources", () => {
|
|
1485
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "ServiceTag", {
|
|
1486
|
+
name: "service-tag",
|
|
1487
|
+
ruleCollectionId: ruleCollection.id,
|
|
1488
|
+
priority: 100,
|
|
1489
|
+
action: "Deny",
|
|
1490
|
+
direction: "Inbound",
|
|
1491
|
+
protocol: "Tcp",
|
|
1492
|
+
sources: [
|
|
1493
|
+
{ addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
|
|
1494
|
+
],
|
|
1495
|
+
});
|
|
1496
|
+
expect(rule.props.sources).toEqual([
|
|
1497
|
+
{ addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
|
|
1498
|
+
]);
|
|
1499
|
+
});
|
|
1500
|
+
it("should handle multiple source addresses", () => {
|
|
1501
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "MultipleSources", {
|
|
1502
|
+
name: "multiple-sources",
|
|
1503
|
+
ruleCollectionId: ruleCollection.id,
|
|
1504
|
+
priority: 100,
|
|
1505
|
+
action: "Deny",
|
|
1506
|
+
direction: "Inbound",
|
|
1507
|
+
protocol: "Tcp",
|
|
1508
|
+
sources: [
|
|
1509
|
+
{ addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
|
|
1510
|
+
{ addressPrefix: "192.168.0.0/16", addressPrefixType: "IPPrefix" },
|
|
1511
|
+
],
|
|
1512
|
+
});
|
|
1513
|
+
expect(rule.props.sources).toHaveLength(2);
|
|
1514
|
+
});
|
|
1515
|
+
});
|
|
1516
|
+
describe("Priority Handling", () => {
|
|
1517
|
+
it("should accept low priority number (high priority)", () => {
|
|
1518
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "HighPriority", {
|
|
1519
|
+
name: "high-priority",
|
|
1520
|
+
ruleCollectionId: ruleCollection.id,
|
|
1521
|
+
priority: 1,
|
|
1522
|
+
action: "AlwaysAllow",
|
|
1523
|
+
direction: "Inbound",
|
|
1524
|
+
protocol: "Any",
|
|
1525
|
+
});
|
|
1526
|
+
expect(rule.rulePriority).toBe(1);
|
|
1527
|
+
});
|
|
1528
|
+
it("should accept high priority number (low priority)", () => {
|
|
1529
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "LowPriority", {
|
|
1530
|
+
name: "low-priority",
|
|
1531
|
+
ruleCollectionId: ruleCollection.id,
|
|
1532
|
+
priority: 4096,
|
|
1533
|
+
action: "Allow",
|
|
1534
|
+
direction: "Inbound",
|
|
1535
|
+
protocol: "Any",
|
|
1536
|
+
});
|
|
1537
|
+
expect(rule.rulePriority).toBe(4096);
|
|
1538
|
+
});
|
|
1539
|
+
});
|
|
1540
|
+
describe("API Version Handling", () => {
|
|
1541
|
+
it("should use default API version when none specified", () => {
|
|
1542
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1543
|
+
name: "test-rule",
|
|
1544
|
+
ruleCollectionId: ruleCollection.id,
|
|
1545
|
+
priority: 100,
|
|
1546
|
+
action: "Deny",
|
|
1547
|
+
direction: "Inbound",
|
|
1548
|
+
protocol: "Tcp",
|
|
1549
|
+
});
|
|
1550
|
+
expect(rule.resolvedApiVersion).toBe("2024-05-01");
|
|
1551
|
+
});
|
|
1552
|
+
it("should use specified API version when provided", () => {
|
|
1553
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1554
|
+
name: "test-rule",
|
|
1555
|
+
ruleCollectionId: ruleCollection.id,
|
|
1556
|
+
apiVersion: "2023-11-01",
|
|
1557
|
+
priority: 100,
|
|
1558
|
+
action: "Deny",
|
|
1559
|
+
direction: "Inbound",
|
|
1560
|
+
protocol: "Tcp",
|
|
1561
|
+
});
|
|
1562
|
+
expect(rule.resolvedApiVersion).toBe("2023-11-01");
|
|
1563
|
+
});
|
|
1564
|
+
});
|
|
1565
|
+
describe("Terraform Outputs", () => {
|
|
1566
|
+
it("should create proper Terraform outputs", () => {
|
|
1567
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1568
|
+
name: "test-rule",
|
|
1569
|
+
ruleCollectionId: ruleCollection.id,
|
|
1570
|
+
priority: 100,
|
|
1571
|
+
action: "Deny",
|
|
1572
|
+
direction: "Inbound",
|
|
1573
|
+
protocol: "Tcp",
|
|
1574
|
+
});
|
|
1575
|
+
expect(rule.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1576
|
+
expect(rule.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1577
|
+
expect(rule.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
1578
|
+
});
|
|
1579
|
+
it("should have proper resource references", () => {
|
|
1580
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1581
|
+
name: "test-rule",
|
|
1582
|
+
ruleCollectionId: ruleCollection.id,
|
|
1583
|
+
priority: 100,
|
|
1584
|
+
action: "Deny",
|
|
1585
|
+
direction: "Inbound",
|
|
1586
|
+
protocol: "Tcp",
|
|
1587
|
+
});
|
|
1588
|
+
expect(rule.id).toMatch(/^\$\{.*\.id\}$/);
|
|
1589
|
+
expect(rule.resourceName).toMatch(/^\$\{.*\.name\}$/);
|
|
1590
|
+
expect(rule.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
|
|
1591
|
+
});
|
|
1592
|
+
});
|
|
1593
|
+
describe("Parent-Child Relationship", () => {
|
|
1594
|
+
it("should correctly reference parent rule collection", () => {
|
|
1595
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1596
|
+
name: "test-rule",
|
|
1597
|
+
ruleCollectionId: ruleCollection.id,
|
|
1598
|
+
priority: 100,
|
|
1599
|
+
action: "Deny",
|
|
1600
|
+
direction: "Inbound",
|
|
1601
|
+
protocol: "Tcp",
|
|
1602
|
+
});
|
|
1603
|
+
expect(rule.props.ruleCollectionId).toBe(ruleCollection.id);
|
|
1604
|
+
});
|
|
1605
|
+
});
|
|
1606
|
+
describe("CDK Synthesis", () => {
|
|
1607
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
1608
|
+
new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
|
|
1609
|
+
name: "test-rule",
|
|
1610
|
+
ruleCollectionId: ruleCollection.id,
|
|
1611
|
+
description: "Test security rule",
|
|
1612
|
+
priority: 100,
|
|
1613
|
+
action: "Deny",
|
|
1614
|
+
direction: "Inbound",
|
|
1615
|
+
protocol: "Tcp",
|
|
1616
|
+
destinationPortRanges: ["22"],
|
|
1617
|
+
});
|
|
1618
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
1619
|
+
expect(synthesized).toBeDefined();
|
|
1620
|
+
const stackConfig = JSON.parse(synthesized);
|
|
1621
|
+
expect(stackConfig.resource).toBeDefined();
|
|
1622
|
+
});
|
|
1623
|
+
});
|
|
1624
|
+
describe("Complex Rule Scenarios", () => {
|
|
1625
|
+
it("should handle rule with all properties specified", () => {
|
|
1626
|
+
const rule = new security_admin_rule_1.SecurityAdminRule(stack, "ComplexRule", {
|
|
1627
|
+
name: "complex-rule",
|
|
1628
|
+
ruleCollectionId: ruleCollection.id,
|
|
1629
|
+
description: "Complex security rule with all properties",
|
|
1630
|
+
priority: 150,
|
|
1631
|
+
action: "Deny",
|
|
1632
|
+
direction: "Inbound",
|
|
1633
|
+
protocol: "Tcp",
|
|
1634
|
+
sourcePortRanges: ["1024-65535"],
|
|
1635
|
+
destinationPortRanges: ["22", "3389"],
|
|
1636
|
+
sources: [
|
|
1637
|
+
{ addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
|
|
1638
|
+
{ addressPrefix: "192.168.0.0/16", addressPrefixType: "IPPrefix" },
|
|
1639
|
+
],
|
|
1640
|
+
destinations: [
|
|
1641
|
+
{ addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
|
|
1642
|
+
],
|
|
1643
|
+
});
|
|
1644
|
+
expect(rule.props.priority).toBe(150);
|
|
1645
|
+
expect(rule.props.sourcePortRanges).toEqual(["1024-65535"]);
|
|
1646
|
+
expect(rule.props.destinationPortRanges).toEqual(["22", "3389"]);
|
|
1647
|
+
expect(rule.props.sources).toHaveLength(2);
|
|
1648
|
+
expect(rule.props.destinations).toHaveLength(1);
|
|
1649
|
+
});
|
|
1650
|
+
});
|
|
1651
|
+
});
|
|
1652
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1uZXR3b3JrLW1hbmFnZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9henVyZS12aXJ0dWFsbmV0d29ya21hbmFnZXIvdGVzdC92aXJ0dWFsLW5ldHdvcmstbWFuYWdlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7OztHQU9HOztBQUVILGlDQUFnQztBQUNoQywrQkFBK0I7QUFDL0Isa0ZBRzJDO0FBQzNDLHdEQUF1RTtBQUN2RSxvRkFHNEM7QUFDNUMsc0ZBRzZDO0FBQzdDLG9FQUdvQztBQUNwQywwRkFHK0M7QUFDL0MsNEVBR3dDO0FBRXhDLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7SUFDckMsSUFBSSxHQUFjLENBQUM7SUFDbkIsSUFBSSxLQUEyQixDQUFDO0lBRWhDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxHQUFHLEdBQUcsZUFBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3RELENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtRQUN6QyxFQUFFLENBQUMsMEVBQTBFLEVBQUUsR0FBRyxFQUFFO1lBQ2xGLE1BQU0sS0FBSyxHQUErQjtnQkFDeEMsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsUUFBUSxFQUFFLFFBQVE7Z0JBQ2xCLGVBQWUsRUFDYiw0RUFBNEU7Z0JBQzlFLG9CQUFvQixFQUFFO29CQUNwQixhQUFhLEVBQUU7d0JBQ2IscURBQXFEO3FCQUN0RDtpQkFDRjtnQkFDRCwyQkFBMkIsRUFBRSxDQUFDLGNBQWMsRUFBRSxlQUFlLENBQUM7YUFDL0QsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksK0NBQXFCLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENB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QUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRTtpQkFDL0Q7YUFDRixDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQzVELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDakUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbXByZWhlbnNpdmUgdGVzdHMgZm9yIHRoZSBWaXJ0dWFsIE5ldHdvcmsgTWFuYWdlciBpbXBsZW1lbnRhdGlvblxuICpcbiAqIFRoaXMgdGVzdCBzdWl0ZSB2YWxpZGF0ZXMgdGhlIFZpcnR1YWxOZXR3b3JrTWFuYWdlciBjbGFzcyBhbmQgYWxsIGNoaWxkIHJlc291cmNlXG4gKiBjb25zdHJ1Y3RzIHVzaW5nIHRoZSBBemFwaVJlc291cmNlIGZyYW1ld29yay4gVGVzdHMgY292ZXIgYXV0b21hdGljIHZlcnNpb24gcmVzb2x1dGlvbixcbiAqIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZywgc2NoZW1hIHZhbGlkYXRpb24sIHByb3BlcnR5IHRyYW5zZm9ybWF0aW9uLCByZXNvdXJjZSBjcmVhdGlvbixcbiAqIGFuZCBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcy5cbiAqL1xuXG5pbXBvcnQgeyBUZXN0aW5nIH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgKiBhcyBjZGt0ZiBmcm9tIFwiY2RrdGZcIjtcbmltcG9ydCB7XG4gIENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24sXG4gIENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyxcbn0gZnJvbSBcIi4uL2xpYi9jb25uZWN0aXZpdHktY29uZmlndXJhdGlvblwiO1xuaW1wb3J0IHsgTmV0d29ya0dyb3VwLCBOZXR3b3JrR3JvdXBQcm9wcyB9IGZyb20gXCIuLi9saWIvbmV0d29yay1ncm91cFwiO1xuaW1wb3J0IHtcbiAgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyLFxuICBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXJQcm9wcyxcbn0gZnJvbSBcIi4uL2xpYi9uZXR3b3JrLWdyb3VwLXN0YXRpYy1tZW1iZXJcIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uLFxuICBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvblByb3BzLFxufSBmcm9tIFwiLi4vbGliL3NlY3VyaXR5LWFkbWluLWNvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5SdWxlLFxuICBTZWN1cml0eUFkbWluUnVsZVByb3BzLFxufSBmcm9tIFwiLi4vbGliL3NlY3VyaXR5LWFkbWluLXJ1bGVcIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbixcbiAgU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uUHJvcHMsXG59IGZyb20gXCIuLi9saWIvc2VjdXJpdHktYWRtaW4tcnVsZS1jb2xsZWN0aW9uXCI7XG5pbXBvcnQge1xuICBWaXJ0dWFsTmV0d29ya01hbmFnZXIsXG4gIFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzLFxufSBmcm9tIFwiLi4vbGliL3ZpcnR1YWwtbmV0d29yay1tYW5hZ2VyXCI7XG5cbmRlc2NyaWJlKFwiVmlydHVhbE5ldHdvcmtNYW5hZ2VyXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvbiBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGEgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aCBtaW5pbXVtIHJlcXVpcmVkIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlcikudG9CZUluc3RhbmNlT2YoVmlydHVhbE5ldHdvcmtNYW5hZ2VyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnJlc291cmNlTmFtZSkudG9CZURlZmluZWQoKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwiTWljcm9zb2Z0Lk5ldHdvcmsvbmV0d29ya01hbmFnZXJzXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGEgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aCBhbGwgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXItZnVsbFwiLFxuICAgICAgICBsb2NhdGlvbjogXCJ3ZXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgbWFuYWdlbWVudEdyb3VwczogW1xuICAgICAgICAgICAgXCIvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VtZW50L21hbmFnZW1lbnRHcm91cHMvbWcxXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJUZXN0IG5ldHdvcmsgbWFuYWdlciB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudDogXCJ0ZXN0XCIsXG4gICAgICAgICAgcHJvamVjdDogXCJjZGt0Zi1jb25zdHJ1Y3RzXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIlRlc3QgbmV0d29yayBtYW5hZ2VyIHdpdGggYWxsIHByb3BlcnRpZXNcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzKS50b0VxdWFsKHtcbiAgICAgICAgZW52aXJvbm1lbnQ6IFwidGVzdFwiLFxuICAgICAgICBwcm9qZWN0OiBcImNka3RmLWNvbnN0cnVjdHNcIixcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KG1hbmFnZXIudGFncykudG9FcXVhbChwcm9wcy50YWdzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJGcmFtZXdvcmsgSW50ZWdyYXRpb24gVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IEFQSSB2ZXJzaW9uIHdoZW4gbm9uZSBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2Ugc3BlY2lmaWVkIEFQSSB2ZXJzaW9uIHdoZW4gcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjMtMTEtMDFcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwiQDIwMjMtMTEtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZWdpc3RlciBzY2hlbWFzIG9uIGZpcnN0IGluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICAvLyBGaXJzdCBpbnN0YW50aWF0aW9uIHNob3VsZCByZWdpc3RlciBzY2hlbWFzXG4gICAgICBjb25zdCBtYW5hZ2VyMSA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIxXCIsIHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyMSkudG9CZUluc3RhbmNlT2YoVmlydHVhbE5ldHdvcmtNYW5hZ2VyKTtcblxuICAgICAgLy8gU2Vjb25kIGluc3RhbnRpYXRpb24gc2hvdWxkIG5vdCByZS1yZWdpc3RlclxuICAgICAgY29uc3QgbWFuYWdlcjIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyMlwiLCB7XG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyLTJcIixcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KG1hbmFnZXIyKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya01hbmFnZXIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlByb3BlcnR5IFZhbGlkYXRpb24gVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlcyB3aXRoIHN1YnNjcmlwdGlvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzExMTExMTExLTExMTEtMTExMS0xMTExLTExMTExMTExMTExMVwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3Blcy5zdWJzY3JpcHRpb25zKS50b0hhdmVMZW5ndGgoMik7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3Blcy5zdWJzY3JpcHRpb25zKS50b0NvbnRhaW4oXG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlcyB3aXRoIG1hbmFnZW1lbnQgZ3JvdXBzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBtYW5hZ2VtZW50R3JvdXBzOiBbXG4gICAgICAgICAgICBcIi9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZW1lbnQvbWFuYWdlbWVudEdyb3Vwcy9tZzFcIixcbiAgICAgICAgICAgIFwiL3Byb3ZpZGVycy9NaWNyb3NvZnQuTWFuYWdlbWVudC9tYW5hZ2VtZW50R3JvdXBzL21nMlwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZXMubWFuYWdlbWVudEdyb3VwcykudG9IYXZlTGVuZ3RoKFxuICAgICAgICAyLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLm1hbmFnZW1lbnRHcm91cHMpLnRvQ29udGFpbihcbiAgICAgICAgXCIvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VtZW50L21hbmFnZW1lbnRHcm91cHMvbWcxXCIsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMgd2l0aCBDb25uZWN0aXZpdHkgYW5kIFNlY3VyaXR5QWRtaW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9Db250YWluKFxuICAgICAgICBcIkNvbm5lY3Rpdml0eVwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9Db250YWluKFxuICAgICAgICBcIlNlY3VyaXR5QWRtaW5cIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBwcm9wZXJseSBmb3JtYXQgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzIHdpdGggUm91dGluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIlJvdXRpbmdcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0NvbnRhaW4oXCJSb3V0aW5nXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRhZyBNYW5hZ2VtZW50IFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhZGQgdGFncyB1c2luZyBhZGRUYWcgbWV0aG9kXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICB0YWdzOiB7XG4gICAgICAgICAgZW52aXJvbm1lbnQ6IFwidGVzdFwiLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBtYW5hZ2VyLmFkZFRhZyhcInByb2plY3RcIiwgXCJuZXR3b3JrLWluZnJhc3RydWN0dXJlXCIpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzIS5wcm9qZWN0KS50b0JlKFwibmV0d29yay1pbmZyYXN0cnVjdHVyZVwiKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLnRhZ3MhLmVudmlyb25tZW50KS50b0JlKFwidGVzdFwiKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwibmV0d29yay1pbmZyYXN0cnVjdHVyZVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHJlbW92ZSB0YWdzIHVzaW5nIHJlbW92ZVRhZyBtZXRob2RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudDogXCJ0ZXN0XCIsXG4gICAgICAgICAgdGVtcG9yYXJ5OiBcInRydWVcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgbWFuYWdlci5yZW1vdmVUYWcoXCJ0ZW1wb3JhcnlcIik7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLnRhZ3MhLnRlbXBvcmFyeSkudG9CZVVuZGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMudGFncyEuZW52aXJvbm1lbnQpLnRvQmUoXCJ0ZXN0XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYWRkIHRhZ3Mgd2hlbiBubyBpbml0aWFsIHRhZ3MgZXhpc3RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIG1hbmFnZXIuYWRkVGFnKFwiZmlyc3RUYWdcIiwgXCJmaXJzdFZhbHVlXCIpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzIS5maXJzdFRhZykudG9CZShcImZpcnN0VmFsdWVcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiVGVycmFmb3JtIE91dHB1dCBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIubG9jYXRpb25PdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci50YWdzT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIuc2NvcGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci5zY29wZUFjY2Vzc2VzT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlcyBpbiBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5pZCkudG9NYXRjaCgvXlxcJFxcey4qXFwuaWRcXH0kLyk7XG4gICAgICBleHBlY3QobWFuYWdlci5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiTGlmZWN5Y2xlIE1hbmFnZW1lbnQgVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGFwcGx5IGlnbm9yZV9jaGFuZ2VzIHdoZW4gc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJ0YWdzXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5pZ25vcmVDaGFuZ2VzKS50b0VxdWFsKFtcInRhZ3NcIl0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBpZ25vcmVfY2hhbmdlcyBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJ0YWdzXCIsIFwiZGVzY3JpcHRpb25cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvQ29udGFpbihcInRhZ3NcIik7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5pZ25vcmVDaGFuZ2VzKS50b0NvbnRhaW4oXCJkZXNjcmlwdGlvblwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzIFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCIsIFwiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBuZXR3b3JrIG1hbmFnZXJcIixcbiAgICAgICAgdGFnczoge1xuICAgICAgICAgIGVudmlyb25tZW50OiBcInRlc3RcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgZXhwZWN0KHN5bnRoZXNpemVkKS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG11bHRpcGxlIFZpcnR1YWwgTmV0d29yayBNYW5hZ2VycyBpbiB0aGUgc2FtZSBzdGFja1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczE6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyLTFcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzMjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXItMlwiLFxuICAgICAgICBsb2NhdGlvbjogXCJ3ZXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8xMTExMTExMS0xMTExLTExMTEtMTExMS0xMTExMTExMTExMTFcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIlNlY3VyaXR5QWRtaW5cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyMSA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIxXCIsIHByb3BzMSk7XG4gICAgICBjb25zdCBtYW5hZ2VyMiA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIyXCIsIHByb3BzMik7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyMS5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTA1LTAxXCIpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjMtMTEtMDFcIik7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB2ZXJpZnkgVGVycmFmb3JtIG91dHB1dCBzdHJ1Y3R1cmVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGNvbnN0IHN0YWNrQ29uZmlnID0gSlNPTi5wYXJzZShzeW50aGVzaXplZCk7XG5cbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0LmlkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLm91dHB1dC5uYW1lKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLm91dHB1dC5sb2NhdGlvbikudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQudGFncykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQuc2NvcGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0LnNjb3BlQWNjZXNzZXMpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUmVzb3VyY2UgVHlwZSBhbmQgVmVyc2lvbiBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgaGF2ZSBjb3JyZWN0IHJlc291cmNlIHR5cGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya01hbmFnZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBhbGwgcmVnaXN0ZXJlZCBBUEkgdmVyc2lvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgdmVyc2lvbnMgPSBbXCIyMDIzLTExLTAxXCIsIFwiMjAyNC0wNS0wMVwiXTtcblxuICAgICAgdmVyc2lvbnMuZm9yRWFjaCgodmVyc2lvbikgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0U3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBgU3RhY2stJHt2ZXJzaW9ufWApO1xuICAgICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihcbiAgICAgICAgICB0ZXN0U3RhY2ssXG4gICAgICAgICAgYE1hbmFnZXItJHt2ZXJzaW9ufWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYG1hbmFnZXItJHt2ZXJzaW9ufWAsXG4gICAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogdmVyc2lvbixcbiAgICAgICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKHZlcnNpb24pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2UgbGF0ZXN0IHZlcnNpb24gYXMgZGVmYXVsdFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJEZXNjcmlwdGlvbiBQcm9wZXJ0eSBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFZpcnR1YWwgTmV0d29yayBNYW5hZ2VyIHdpdGggZGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNlbnRyYWwgbmV0d29yayBtYW5hZ2VtZW50IGZvciBwcm9kdWN0aW9uIHdvcmtsb2Fkc1wiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcbiAgICAgICAgXCJDZW50cmFsIG5ldHdvcmsgbWFuYWdlbWVudCBmb3IgcHJvZHVjdGlvbiB3b3JrbG9hZHNcIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aG91dCBkZXNjcmlwdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMuZGVzY3JpcHRpb24pLnRvQmVVbmRlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJNaXhlZCBTY29wZSBDb25maWd1cmF0aW9uIFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGJvdGggc3Vic2NyaXB0aW9ucyBhbmQgbWFuYWdlbWVudCBncm91cHMgaW4gc2NvcGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtYW5hZ2VtZW50R3JvdXBzOiBbXG4gICAgICAgICAgICBcIi9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZW1lbnQvbWFuYWdlbWVudEdyb3Vwcy9tZzFcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiLCBcIlNlY3VyaXR5QWRtaW5cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLnN1YnNjcmlwdGlvbnMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLm1hbmFnZW1lbnRHcm91cHMpLnRvSGF2ZUxlbmd0aChcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGFsbCB0aHJlZSBzY29wZSBhY2Nlc3MgdHlwZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXG4gICAgICAgICAgXCJDb25uZWN0aXZpdHlcIixcbiAgICAgICAgICBcIlNlY3VyaXR5QWRtaW5cIixcbiAgICAgICAgICBcIlJvdXRpbmdcIixcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0hhdmVMZW5ndGgoMyk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvQ29udGFpbihcbiAgICAgICAgXCJDb25uZWN0aXZpdHlcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvQ29udGFpbihcbiAgICAgICAgXCJTZWN1cml0eUFkbWluXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0NvbnRhaW4oXCJSb3V0aW5nXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNvbnZlbmllbmNlIE1ldGhvZHMgZm9yIENoaWxkIFJlc291cmNlc1wiLCAoKSA9PiB7XG4gICAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCIsIFwiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE5ldHdvcmtHcm91cCB1c2luZyBjb252ZW5pZW5jZSBtZXRob2RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbWFuYWdlci5hZGROZXR3b3JrR3JvdXAoXCJwcm9kLWdyb3VwXCIsIHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXZuZXRzXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3Jrc1wiLFxuICAgICAgICBtZW1iZXJUeXBlOiBcIlZpcnR1YWxOZXR3b3JrXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cCkudG9CZUluc3RhbmNlT2YoTmV0d29ya0dyb3VwKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMubmV0d29ya01hbmFnZXJJZCkudG9CZShtYW5hZ2VyLmlkKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMubmFtZSkudG9CZShcInByb2R1Y3Rpb24tdm5ldHNcIik7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3Jrc1wiLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uIHVzaW5nIGNvbnZlbmllbmNlIG1ldGhvZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBtYW5hZ2VyLmFkZE5ldHdvcmtHcm91cChcInByb2QtZ3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInByb2R1Y3Rpb24tdm5ldHNcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb25uZWN0aXZpdHlDb25maWcgPSBtYW5hZ2VyLmFkZENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24oXG4gICAgICAgIFwiaHViLXNwb2tlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInByb2R1Y3Rpb24taHViLXNwb2tlXCIsXG4gICAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiSHViQW5kU3Bva2VcIixcbiAgICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgICAgICAgZ3JvdXBDb25uZWN0aXZpdHk6IFwiTm9uZVwiLFxuICAgICAgICAgICAgICB1c2VIdWJHYXRld2F5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGh1YnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy9odWJcIixcbiAgICAgICAgICAgICAgcmVzb3VyY2VUeXBlOiBcIk1pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3Jrc1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpdml0eUNvbmZpZykudG9CZUluc3RhbmNlT2YoQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29ubmVjdGl2aXR5Q29uZmlnLnByb3BzLm5ldHdvcmtNYW5hZ2VySWQpLnRvQmUobWFuYWdlci5pZCk7XG4gICAgICBleHBlY3QoY29ubmVjdGl2aXR5Q29uZmlnLnByb3BzLmNvbm5lY3Rpdml0eVRvcG9sb2d5KS50b0JlKFwiSHViQW5kU3Bva2VcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24gdXNpbmcgY29udmVuaWVuY2UgbWV0aG9kXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlY3VyaXR5Q29uZmlnID0gbWFuYWdlci5hZGRTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihcInNlY3VyaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXNlY3VyaXR5XCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkhpZ2gtcHJpb3JpdHkgc2VjdXJpdHkgcnVsZXNcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc2VjdXJpdHlDb25maWcpLnRvQmVJbnN0YW5jZU9mKFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKTtcbiAgICAgIGV4cGVjdChzZWN1cml0eUNvbmZpZy5wcm9wcy5uZXR3b3JrTWFuYWdlcklkKS50b0JlKG1hbmFnZXIuaWQpO1xuICAgICAgZXhwZWN0KHNlY3VyaXR5Q29uZmlnLnByb3BzLm5hbWUpLnRvQmUoXCJwcm9kdWN0aW9uLXNlY3VyaXR5XCIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIk5ldHdvcmtHcm91cFwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNka3RmLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGt0Zi5UZXJyYWZvcm1TdGFjaztcbiAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKGFwcCwgXCJ0ZXN0LXN0YWNrXCIpO1xuICAgIG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1tYW5hZ2VyXCIsXG4gICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uczogW1wiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCJdLFxuICAgICAgfSxcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBOZXR3b3JrR3JvdXAgd2l0aCBtaW5pbXVtIHJlcXVpcmVkIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IE5ldHdvcmtHcm91cFByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cCkudG9CZUluc3RhbmNlT2YoTmV0d29ya0dyb3VwKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMpLnRvQmUocHJvcHMpO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvdXJjZU5hbWUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLmlkKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE5ldHdvcmtHcm91cCB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBOZXR3b3JrR3JvdXBQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXZuZXRzXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3JrcyBmb3IgRWFzdCBVU1wiLFxuICAgICAgICBtZW1iZXJUeXBlOiBcIlZpcnR1YWxOZXR3b3JrXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMuZGVzY3JpcHRpb24pLnRvQmUoXG4gICAgICAgIFwiUHJvZHVjdGlvbiB2aXJ0dWFsIG5ldHdvcmtzIGZvciBFYXN0IFVTXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5wcm9wcy5tZW1iZXJUeXBlKS50b0JlKFwiVmlydHVhbE5ldHdvcmtcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgTmV0d29ya0dyb3VwIHdpdGggU3VibmV0IG1lbWJlciB0eXBlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBOZXR3b3JrR3JvdXBQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJzdWJuZXQtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgbWVtYmVyVHlwZTogXCJTdWJuZXRcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiU3VibmV0LWxldmVsIG5ldHdvcmsgZ3JvdXBcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiU3VibmV0R3JvdXBcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLm1lbWJlclR5cGUpLnRvQmUoXCJTdWJuZXRcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQVBJIFZlcnNpb24gSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IEFQSSB2ZXJzaW9uIHdoZW4gbm9uZSBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2Ugc3BlY2lmaWVkIEFQSSB2ZXJzaW9uIHdoZW4gcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWdyb3VwXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5pZE91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAubmFtZU91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAuaWQpLnRvTWF0Y2goL15cXCRcXHsuKlxcLmlkXFx9JC8pO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3Zpc2lvbmluZ1N0YXRlKS50b01hdGNoKFxuICAgICAgICAvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnByb3Zpc2lvbmluZ1N0YXRlXFx9JC8sXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkxpZmVjeWNsZSBNYW5hZ2VtZW50XCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhcHBseSBpZ25vcmVfY2hhbmdlcyB3aGVuIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJkZXNjcmlwdGlvblwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvRXF1YWwoW1wiZGVzY3JpcHRpb25cIl0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNESyBTeW50aGVzaXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN5bnRoZXNpemUgdmFsaWQgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBuZXR3b3JrIGdyb3VwXCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9CZURlZmluZWQoKTtcbiAgICAgIGNvbnN0IHN0YWNrQ29uZmlnID0gSlNPTi5wYXJzZShzeW50aGVzaXplZCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcucmVzb3VyY2UpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuICBsZXQgbmV0d29ya0dyb3VwOiBOZXR3b3JrR3JvdXA7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gVGVzdGluZy5hcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGt0Zi5UZXJyYWZvcm1TdGFjayhhcHAsIFwidGVzdC1zdGFja1wiKTtcbiAgICBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCB7XG4gICAgICBuYW1lOiBcInRlc3QtbWFuYWdlclwiLFxuICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiXSxcbiAgICAgIH0sXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICB9KTtcbiAgICBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFN0YXRpY01lbWJlciBmb3IgVk5ldFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidm5ldC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya3MvdGVzdC12bmV0XCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtZW1iZXIgPSBuZXcgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyKHN0YWNrLCBcIlZuZXRNZW1iZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWVtYmVyKS50b0JlSW5zdGFuY2VPZihOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIpO1xuICAgICAgZXhwZWN0KG1lbWJlci5wcm9wcykudG9CZShwcm9wcyk7XG4gICAgICBleHBlY3QobWVtYmVyLnByb3BzLnJlc291cmNlSWQpLnRvQ29udGFpbihcInZpcnR1YWxOZXR3b3Jrc1wiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTdGF0aWNNZW1iZXIgZm9yIFN1Ym5ldFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwic3VibmV0LW1lbWJlclwiLFxuICAgICAgICBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkLFxuICAgICAgICByZXNvdXJjZUlkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3Jrcy90ZXN0LXZuZXQvc3VibmV0cy90ZXN0LXN1Ym5ldFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWVtYmVyID0gbmV3IE5ldHdvcmtHcm91cFN0YXRpY01lbWJlcihzdGFjaywgXCJTdWJuZXRNZW1iZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWVtYmVyKS50b0JlSW5zdGFuY2VPZihOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIpO1xuICAgICAgZXhwZWN0KG1lbWJlci5wcm9wcy5yZXNvdXJjZUlkKS50b0NvbnRhaW4oXCJzdWJuZXRzXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZW1iZXIgPSBuZXcgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyKHN0YWNrLCBcIlRlc3RNZW1iZXJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtbWVtYmVyXCIsXG4gICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgIHJlc291cmNlSWQ6IFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3Mvdm5ldDFcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG1lbWJlci5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWVtYmVyLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWVtYmVyLnJlc291cmNlSWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIHByb3BlciByZXNvdXJjZSByZWZlcmVuY2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIuaWQpLnRvTWF0Y2goL15cXCRcXHsuKlxcLmlkXFx9JC8pO1xuICAgICAgZXhwZWN0KG1lbWJlci5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgICAvLyBtZW1iZXJSZXNvdXJjZUlkIHJldHVybnMgdGhlIGlucHV0IHJlc291cmNlSWQgc2luY2UgQXp1cmUgQVBJIGRvZXNuJ3QgcmV0dXJuIGl0XG4gICAgICBleHBlY3QobWVtYmVyLm1lbWJlclJlc291cmNlSWQpLnRvQmUoXG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3Mvdm5ldDFcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWVtYmVyLnJlZ2lvbikudG9NYXRjaCgvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnJlZ2lvblxcfSQvKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQYXJlbnQtQ2hpbGQgUmVsYXRpb25zaGlwXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjb3JyZWN0bHkgcmVmZXJlbmNlIHBhcmVudCBuZXR3b3JrIGdyb3VwXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIucHJvcHMubmV0d29ya0dyb3VwSWQpLnRvQmUobmV0d29ya0dyb3VwLmlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIkNvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICBsZXQgYXBwOiBjZGt0Zi5BcHA7XG4gIGxldCBzdGFjazogY2RrdGYuVGVycmFmb3JtU3RhY2s7XG4gIGxldCBtYW5hZ2VyOiBWaXJ0dWFsTmV0d29ya01hbmFnZXI7XG4gIGxldCBuZXR3b3JrR3JvdXA6IE5ldHdvcmtHcm91cDtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKGFwcCwgXCJ0ZXN0LXN0YWNrXCIpO1xuICAgIG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1tYW5hZ2VyXCIsXG4gICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uczogW1wiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCJdLFxuICAgICAgfSxcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gTWVzaCBUb3BvbG9neVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE1lc2ggY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJtZXNoLWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJEaXJlY3RseUNvbm5lY3RlZFwiLFxuICAgICAgICAgICAgaXNHbG9iYWw6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJNZXNoQ29uZmlnXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZykudG9CZUluc3RhbmNlT2YoQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29uZmlnLnRvcG9sb2d5KS50b0JlKFwiTWVzaFwiKTtcbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuYXBwbGllc1RvR3JvdXBzKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgZ2xvYmFsIE1lc2ggY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJnbG9iYWwtbWVzaFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJEaXJlY3RseUNvbm5lY3RlZFwiLFxuICAgICAgICAgICAgaXNHbG9iYWw6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaXNHbG9iYWw6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJHbG9iYWxNZXNoXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5pc0dsb2JhbCkudG9CZSh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gSHViLWFuZC1TcG9rZSBUb3BvbG9neVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIEh1Yi1hbmQtU3Bva2UgY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJodWItc3Bva2UtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIkh1YkFuZFNwb2tlXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJOb25lXCIsXG4gICAgICAgICAgICB1c2VIdWJHYXRld2F5OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGh1YnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUlkOiBcIi9zdWJzY3JpcHRpb25zL3Rlc3QvdmlydHVhbE5ldHdvcmtzL2h1Yi12bmV0XCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJIdWJTcG9rZUNvbmZpZ1wiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25maWcudG9wb2xvZ3kpLnRvQmUoXCJIdWJBbmRTcG9rZVwiKTtcbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuaHVicykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5hcHBsaWVzVG9Hcm91cHNbMF0udXNlSHViR2F0ZXdheSkudG9CZSh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBIdWItYW5kLVNwb2tlIHdpdGggbXVsdGlwbGUgaHVic1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcIm11bHRpLWh1Yi1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiSHViQW5kU3Bva2VcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgICAgIGdyb3VwQ29ubmVjdGl2aXR5OiBcIk5vbmVcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBodWJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy9odWItdm5ldC0xXCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUlkOiBcIi9zdWJzY3JpcHRpb25zL3Rlc3QvdmlydHVhbE5ldHdvcmtzL2h1Yi12bmV0LTJcIixcbiAgICAgICAgICAgIHJlc291cmNlVHlwZTogXCJNaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya3NcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uZmlnID0gbmV3IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIk11bHRpSHViQ29uZmlnXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5odWJzKS50b0hhdmVMZW5ndGgoMik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJvcGVydHkgVmFsaWRhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGRlc2NyaXB0aW9uIHByb3BlcnR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkh1Yi1hbmQtc3Bva2UgdG9wb2xvZ3kgZm9yIHByb2R1Y3Rpb24gd29ya2xvYWRzXCIsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIkh1YkFuZFNwb2tlXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgaHViczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlc291cmNlSWQ6IFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3MvaHViXCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY29uZmlnLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIkh1Yi1hbmQtc3Bva2UgdG9wb2xvZ3kgZm9yIHByb2R1Y3Rpb24gd29ya2xvYWRzXCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGRlbGV0ZUV4aXN0aW5nUGVlcmluZyBwcm9wZXJ0eVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJUZXN0Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgZGVsZXRlRXhpc3RpbmdQZWVyaW5nOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuZGVsZXRlRXhpc3RpbmdQZWVyaW5nKS50b0JlKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJUZXN0Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjMtMTEtMDFcIixcbiAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiTWVzaFwiLFxuICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFt7IG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQgfV0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3Zpc2lvbmluZ1N0YXRlT3V0cHV0KS50b0JlSW5zdGFuY2VPZihcbiAgICAgICAgY2RrdGYuVGVycmFmb3JtT3V0cHV0LFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbiB3aXRoIG1pbmltdW0gcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJzZWN1cml0eS1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiU2VjdXJpdHlDb25maWdcIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29uZmlnKS50b0JlSW5zdGFuY2VPZihTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbiB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInNlY3VyaXR5LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJPcmdhbml6YXRpb24td2lkZSBzZWN1cml0eSBydWxlc1wiLFxuICAgICAgICBhcHBseU9uTmV0d29ya0ludGVudFBvbGljeUJhc2VkU2VydmljZXM6IFtcIk5vbmVcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlNlY3VyaXR5Q29uZmlnXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcIk9yZ2FuaXphdGlvbi13aWRlIHNlY3VyaXR5IHJ1bGVzXCIpO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5hcHBseU9uTmV0d29ya0ludGVudFBvbGljeUJhc2VkU2VydmljZXMpLnRvRXF1YWwoW1xuICAgICAgICBcIk5vbmVcIixcbiAgICAgIF0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTA1LTAxXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdXNlIHNwZWNpZmllZCBBUEkgdmVyc2lvbiB3aGVuIHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGFwaVZlcnNpb246IFwiMjAyMy0xMS0wMVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24oc3RhY2ssIFwiU2VjdXJpdHlDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInNlY3VyaXR5LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3Zpc2lvbmluZ1N0YXRlT3V0cHV0KS50b0JlSW5zdGFuY2VPZihcbiAgICAgICAgY2RrdGYuVGVycmFmb3JtT3V0cHV0LFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgcHJvcGVyIHJlc291cmNlIHJlZmVyZW5jZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJzZWN1cml0eS1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY29uZmlnLmlkKS50b01hdGNoKC9eXFwkXFx7LipcXC5pZFxcfSQvKTtcbiAgICAgIGV4cGVjdChjb25maWcucmVzb3VyY2VOYW1lKS50b01hdGNoKC9eXFwkXFx7LipcXC5uYW1lXFx9JC8pO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm92aXNpb25pbmdTdGF0ZSkudG9NYXRjaChcbiAgICAgICAgL15cXCRcXHsuKlxcLm91dHB1dFxcLnByb3BlcnRpZXNcXC5wcm92aXNpb25pbmdTdGF0ZVxcfSQvLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRlc3Qgc2VjdXJpdHkgY29uZmlndXJhdGlvblwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvblwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNka3RmLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGt0Zi5UZXJyYWZvcm1TdGFjaztcbiAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcbiAgbGV0IHNlY3VyaXR5Q29uZmlnOiBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbjtcbiAgbGV0IG5ldHdvcmtHcm91cDogTmV0d29ya0dyb3VwO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICAgIHNlY3VyaXR5Q29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgUnVsZUNvbGxlY3Rpb24gd2l0aCBtaW5pbXVtIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlJ1bGVDb2xsZWN0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbik7XG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5hcHBsaWVzVG9Hcm91cHMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBSdWxlQ29sbGVjdGlvbiB3aXRoIGRlc2NyaXB0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJibG9jay1oaWdoLXJpc2stcG9ydHNcIixcbiAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1bGVzIHRvIGJsb2NrIGhpZ2gtcmlzayBwb3J0c1wiLFxuICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFt7IG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQgfV0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcbiAgICAgICAgXCJSdWxlcyB0byBibG9jayBoaWdoLXJpc2sgcG9ydHNcIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgUnVsZUNvbGxlY3Rpb24gYXBwbGllZCB0byBtdWx0aXBsZSBncm91cHNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZ3JvdXAyID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXAyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWdyb3VwLTJcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwibXVsdGktZ3JvdXAtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbXG4gICAgICAgICAgeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH0sXG4gICAgICAgICAgeyBuZXR3b3JrR3JvdXBJZDogZ3JvdXAyLmlkIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5hcHBsaWVzVG9Hcm91cHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJBUEkgVmVyc2lvbiBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgdXNlIGRlZmF1bHQgQVBJIHZlcnNpb24gd2hlbiBub25lIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24uaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBhcmVudC1DaGlsZCBSZWxhdGlvbnNoaXBcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNvcnJlY3RseSByZWZlcmVuY2UgcGFyZW50IHNlY3VyaXR5IGFkbWluIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlJ1bGVDb2xsZWN0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICAgIHNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQ6IHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb2xsZWN0aW9uLnByb3BzLnNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQpLnRvQmUoXG4gICAgICAgIHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oc3RhY2ssIFwiUnVsZUNvbGxlY3Rpb25cIiwge1xuICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5SdWxlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuICBsZXQgc2VjdXJpdHlDb25maWc6IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uO1xuICBsZXQgbmV0d29ya0dyb3VwOiBOZXR3b3JrR3JvdXA7XG4gIGxldCBydWxlQ29sbGVjdGlvbjogU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICAgIHNlY3VyaXR5Q29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgICBydWxlQ29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oc3RhY2ssIFwiUnVsZUNvbGxlY3Rpb25cIiwge1xuICAgICAgbmFtZTogXCJydWxlLWNvbGxlY3Rpb25cIixcbiAgICAgIHNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQ6IHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb24gLSBEZW55IFJ1bGVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgRGVueSBydWxlIGJsb2NraW5nIFNTSFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJibG9jay1zc2hcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkJsb2NrIFNTSCBhY2Nlc3MgZnJvbSBpbnRlcm5ldFwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0UmFuZ2VzOiBbXCIyMlwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGVzdGluYXRpb25zOiBbeyBhZGRyZXNzUHJlZml4OiBcIipcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9XSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQmxvY2tTU0hcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QocnVsZSkudG9CZUluc3RhbmNlT2YoU2VjdXJpdHlBZG1pblJ1bGUpO1xuICAgICAgZXhwZWN0KHJ1bGUucnVsZUFjdGlvbikudG9CZShcIkRlbnlcIik7XG4gICAgICBleHBlY3QocnVsZS5ydWxlUHJpb3JpdHkpLnRvQmUoMTAwKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiVGNwXCIpO1xuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMuZGVzdGluYXRpb25Qb3J0UmFuZ2VzKS50b0VxdWFsKFtcIjIyXCJdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBEZW55IHJ1bGUgYmxvY2tpbmcgUkRQXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZVByb3BzID0ge1xuICAgICAgICBuYW1lOiBcImJsb2NrLXJkcFwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMSxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIGRlc3RpbmF0aW9uUG9ydFJhbmdlczogW1wiMzM4OVwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGVzdGluYXRpb25zOiBbeyBhZGRyZXNzUHJlZml4OiBcIipcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9XSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQmxvY2tSRFBcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMzM4OVwiXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvbiAtIEFsbG93IFJ1bGVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgQWxsb3cgcnVsZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJhbGxvdy1odHRwc1wiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDIwMCxcbiAgICAgICAgYWN0aW9uOiBcIkFsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjQ0M1wiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQWxsb3dIVFRQU1wiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVBY3Rpb24pLnRvQmUoXCJBbGxvd1wiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gQWx3YXlzQWxsb3cgUnVsZXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBBbHdheXNBbGxvdyBydWxlIGZvciBtb25pdG9yaW5nXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZVByb3BzID0ge1xuICAgICAgICBuYW1lOiBcImFsd2F5cy1hbGxvdy1tb25pdG9yaW5nXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJBbHdheXMgYWxsb3cgdHJhZmZpYyBmcm9tIG1vbml0b3Jpbmcgc3lzdGVtc1wiLFxuICAgICAgICBwcmlvcml0eTogNTAsXG4gICAgICAgIGFjdGlvbjogXCJBbHdheXNBbGxvd1wiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJBbnlcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC8yNFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJJUFByZWZpeFwiIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRlc3RpbmF0aW9uczogW3sgYWRkcmVzc1ByZWZpeDogXCIqXCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfV0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkFsbG93TW9uaXRvcmluZ1wiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVBY3Rpb24pLnRvQmUoXCJBbHdheXNBbGxvd1wiKTtcbiAgICAgIGV4cGVjdChydWxlLnJ1bGVQcmlvcml0eSkudG9CZSg1MCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJvdG9jb2wgSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgVGNwIHByb3RvY29sXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGNwUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwidGNwLXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiVGNwXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBVZHAgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJVZHBSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ1ZHAtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVWRwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJvdG9jb2wpLnRvQmUoXCJVZHBcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IEljbXAgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJJY21wUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwiaWNtcC1ydWxlXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJJY21wXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJvdG9jb2wpLnRvQmUoXCJJY21wXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBBbnkgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJBbnlSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJhbnktcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkFsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiQW55XCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkRpcmVjdGlvbiBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBJbmJvdW5kIGRpcmVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkluYm91bmRSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJpbmJvdW5kLXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRpcmVjdGlvbikudG9CZShcIkluYm91bmRcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IE91dGJvdW5kIGRpcmVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIk91dGJvdW5kUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwib3V0Ym91bmQtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIk91dGJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRpcmVjdGlvbikudG9CZShcIk91dGJvdW5kXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBvcnQgUmFuZ2UgSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBzaW5nbGUgc291cmNlIHBvcnRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJTaW5nbGVQb3J0XCIsIHtcbiAgICAgICAgbmFtZTogXCJzaW5nbGUtcG9ydFwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIHNvdXJjZVBvcnRSYW5nZXM6IFtcIjgwXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiODBcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG11bHRpcGxlIGRlc3RpbmF0aW9uIHBvcnRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiTXVsdGlwbGVQb3J0c1wiLCB7XG4gICAgICAgIG5hbWU6IFwibXVsdGlwbGUtcG9ydHNcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjgwXCIsIFwiNDQzXCIsIFwiODA4MFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiODBcIiwgXCI0NDNcIiwgXCI4MDgwXCJdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBwb3J0IHJhbmdlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlBvcnRSYW5nZVwiLCB7XG4gICAgICAgIG5hbWU6IFwicG9ydC1yYW5nZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIGRlc3RpbmF0aW9uUG9ydFJhbmdlczogW1wiODAwMC04OTk5XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9uUG9ydFJhbmdlcykudG9FcXVhbChbXCI4MDAwLTg5OTlcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgZGVmYXVsdCB0byB3aWxkY2FyZCB3aGVuIHBvcnRzIG5vdCBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJEZWZhdWx0UG9ydHNcIiwge1xuICAgICAgICBuYW1lOiBcImRlZmF1bHQtcG9ydHNcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9uUG9ydFJhbmdlcykudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFkZHJlc3MgUHJlZml4IEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgSVAgcHJlZml4IHNvdXJjZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJJUFByZWZpeFwiLCB7XG4gICAgICAgIG5hbWU6IFwiaXAtcHJlZml4XCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC84XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5zb3VyY2VzKS50b0VxdWFsKFtcbiAgICAgICAgeyBhZGRyZXNzUHJlZml4OiBcIjEwLjAuMC4wLzhcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgU2VydmljZVRhZyBzb3VyY2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiU2VydmljZVRhZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VydmljZS10YWdcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBzb3VyY2VzOiBbXG4gICAgICAgICAgeyBhZGRyZXNzUHJlZml4OiBcIkludGVybmV0XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIlNlcnZpY2VUYWdcIiB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvRXF1YWwoW1xuICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiSW50ZXJuZXRcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiU2VydmljZVRhZ1wiIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBzb3VyY2UgYWRkcmVzc2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiTXVsdGlwbGVTb3VyY2VzXCIsIHtcbiAgICAgICAgbmFtZTogXCJtdWx0aXBsZS1zb3VyY2VzXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC84XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfSxcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTkyLjE2OC4wLjAvMTZcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQcmlvcml0eSBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgYWNjZXB0IGxvdyBwcmlvcml0eSBudW1iZXIgKGhpZ2ggcHJpb3JpdHkpXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiSGlnaFByaW9yaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJoaWdoLXByaW9yaXR5XCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMSxcbiAgICAgICAgYWN0aW9uOiBcIkFsd2F5c0FsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVQcmlvcml0eSkudG9CZSgxKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGFjY2VwdCBoaWdoIHByaW9yaXR5IG51bWJlciAobG93IHByaW9yaXR5KVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkxvd1ByaW9yaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJsb3ctcHJpb3JpdHlcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiA0MDk2LFxuICAgICAgICBhY3Rpb246IFwiQWxsb3dcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiQW55XCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucnVsZVByaW9yaXR5KS50b0JlKDQwOTYpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGVzdFJ1bGVcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGFwaVZlcnNpb246IFwiMjAyMy0xMS0wMVwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGVzdFJ1bGVcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QocnVsZS5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KHJ1bGUucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLmlkKS50b01hdGNoKC9eXFwkXFx7LipcXC5pZFxcfSQvKTtcbiAgICAgIGV4cGVjdChydWxlLnJlc291cmNlTmFtZSkudG9NYXRjaCgvXlxcJFxcey4qXFwubmFtZVxcfSQvKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3Zpc2lvbmluZ1N0YXRlKS50b01hdGNoKFxuICAgICAgICAvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnByb3Zpc2lvbmluZ1N0YXRlXFx9JC8sXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBhcmVudC1DaGlsZCBSZWxhdGlvbnNoaXBcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNvcnJlY3RseSByZWZlcmVuY2UgcGFyZW50IHJ1bGUgY29sbGVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnJ1bGVDb2xsZWN0aW9uSWQpLnRvQmUocnVsZUNvbGxlY3Rpb24uaWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNESyBTeW50aGVzaXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN5bnRoZXNpemUgdmFsaWQgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRlc3Qgc2VjdXJpdHkgcnVsZVwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0UmFuZ2VzOiBbXCIyMlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgZXhwZWN0KHN5bnRoZXNpemVkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDb21wbGV4IFJ1bGUgU2NlbmFyaW9zXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgcnVsZSB3aXRoIGFsbCBwcm9wZXJ0aWVzIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkNvbXBsZXhSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJjb21wbGV4LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbXBsZXggc2VjdXJpdHkgcnVsZSB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsXG4gICAgICAgIHByaW9yaXR5OiAxNTAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBzb3VyY2VQb3J0UmFuZ2VzOiBbXCIxMDI0LTY1NTM1XCJdLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjIyXCIsIFwiMzM4OVwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTkyLjE2OC4wLjAvMTZcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXN0aW5hdGlvbnM6IFtcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTAuMC4wLjAvOFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJJUFByZWZpeFwiIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJpb3JpdHkpLnRvQmUoMTUwKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMTAyNC02NTUzNVwiXSk7XG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMjJcIiwgXCIzMzg5XCJdKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9ucykudG9IYXZlTGVuZ3RoKDEpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|