UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

293 lines 30.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedshiftData = void 0; const shared_1 = require("../../shared"); /** * Statement provider for service [redshift-data](https://docs.aws.amazon.com/service-authorization/latest/reference/list_redshift-data.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ class RedshiftData extends shared_1.PolicyStatement { /** * Grants permission to execute multiple queries under a single connection * * Access Level: Write * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_BatchExecuteStatement.html */ toBatchExecuteStatement() { return this.to('BatchExecuteStatement'); } /** * Grants permission to cancel a running query * * Access Level: Write * * Possible conditions: * - .ifStatementOwnerIamUserid() * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_CancelStatement.html */ toCancelStatement() { return this.to('CancelStatement'); } /** * Grants permission to retrieve detailed information about a statement execution * * Access Level: Read * * Possible conditions: * - .ifStatementOwnerIamUserid() * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_DescribeStatement.html */ toDescribeStatement() { return this.to('DescribeStatement'); } /** * Grants permission to retrieve metadata about a particular table * * Access Level: Read * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_DescribeTable.html */ toDescribeTable() { return this.to('DescribeTable'); } /** * Grants permission to execute a query * * Access Level: Write * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html */ toExecuteStatement() { return this.to('ExecuteStatement'); } /** * Grants permission to get staging bucket location for a given managed workgroup * * Access Level: Read * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_GetStagingBucketLocation.html */ toGetStagingBucketLocation() { return this.to('GetStagingBucketLocation'); } /** * Grants permission to fetch the result of a query * * Access Level: Read * * Possible conditions: * - .ifStatementOwnerIamUserid() * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_GetStatementResult.html */ toGetStatementResult() { return this.to('GetStatementResult'); } /** * Grants permission to list databases for a given cluster * * Access Level: Read * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ListDatabases.html */ toListDatabases() { return this.to('ListDatabases'); } /** * Grants permission to list schemas for a given cluster * * Access Level: Read * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ListSchemas.html */ toListSchemas() { return this.to('ListSchemas'); } /** * Grants permission to list sessions for a given principal * * Access Level: List * * Possible conditions: * - .ifSessionOwnerIamUserid() * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ListSessions.html */ toListSessions() { return this.to('ListSessions'); } /** * Grants permission to list queries for a given principal * * Access Level: List * * Possible conditions: * - .ifStatementOwnerIamUserid() * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ListStatements.html */ toListStatements() { return this.to('ListStatements'); } /** * Grants permission to list tables for a given cluster * * Access Level: List * * https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ListTables.html */ toListTables() { return this.to('ListTables'); } /** * Adds a resource of type cluster to the statement * * https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html * * @param clusterName - Identifier for the clusterName. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. * * Possible conditions: * - .ifAwsResourceTag() */ onCluster(clusterName, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:redshift:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:cluster:${clusterName}`); } /** * Adds a resource of type managed-workgroup to the statement * * https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-serverless.html * * @param managedWorkgroupId - Identifier for the managedWorkgroupId. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. */ onManagedWorkgroup(managedWorkgroupId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:redshift-serverless:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:managed-workgroup/${managedWorkgroupId}`); } /** * Adds a resource of type workgroup to the statement * * https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-serverless.html * * @param workgroupId - Identifier for the workgroupId. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. * * Possible conditions: * - .ifAwsResourceTag() */ onWorkgroup(workgroupId, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:redshift-serverless:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:workgroup/${workgroupId}`); } /** * Filters access by tag-value associated with the resource * * https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-overview.html#redshift-policy-resources.conditions * * Applies to actions: * - .toBatchExecuteStatement() * - .toDescribeTable() * - .toExecuteStatement() * - .toListDatabases() * - .toListSchemas() * - .toListTables() * * Applies to resource types: * - cluster * - workgroup * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsResourceTag(tagKey, value, operator) { return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by glue catalog arn * * https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-overview.html#redshift-policy-resources.conditions * * Applies to actions: * - .toBatchExecuteStatement() * - .toExecuteStatement() * * @param value The value(s) to check * @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike` */ ifGlueCatalogArn(value, operator) { return this.if(`glue-catalog-arn`, value, operator ?? 'ArnLike'); } /** * Filters access by session owner iam userid * * https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-overview.html#redshift-policy-resources.conditions * * Applies to actions: * - .toBatchExecuteStatement() * - .toExecuteStatement() * - .toListSessions() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifSessionOwnerIamUserid(value, operator) { return this.if(`session-owner-iam-userid`, value, operator ?? 'StringLike'); } /** * Filters access by statement owner iam userid * * https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-overview.html#redshift-policy-resources.conditions * * Applies to actions: * - .toCancelStatement() * - .toDescribeStatement() * - .toGetStatementResult() * - .toListStatements() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifStatementOwnerIamUserid(value, operator) { return this.if(`statement-owner-iam-userid`, value, operator ?? 'StringLike'); } /** * Statement provider for service [redshift-data](https://docs.aws.amazon.com/service-authorization/latest/reference/list_redshift-data.html). * */ constructor(props) { super(props); this.servicePrefix = 'redshift-data'; this.accessLevelList = { Write: [ 'BatchExecuteStatement', 'CancelStatement', 'ExecuteStatement' ], Read: [ 'DescribeStatement', 'DescribeTable', 'GetStagingBucketLocation', 'GetStatementResult', 'ListDatabases', 'ListSchemas' ], List: [ 'ListSessions', 'ListStatements', 'ListTables' ] }; } } exports.RedshiftData = RedshiftData; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkc2hpZnQtZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInJlZHNoaWZ0LWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLFlBQWEsU0FBUSx3QkFBZTtJQUcvQzs7Ozs7O09BTUc7SUFDSSx1QkFBdUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGlCQUFpQjtRQUN0QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksbUJBQW1CO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxlQUFlO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSwwQkFBMEI7UUFDL0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMs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O2dCQUNuQixlQUFlO2dCQUNmLDBCQUEwQjtnQkFDMUIsb0JBQW9CO2dCQUNwQixlQUFlO2dCQUNmLGFBQWE7YUFDZDtZQUNELElBQUksRUFBRTtnQkFDSixjQUFjO2dCQUNkLGdCQUFnQjtnQkFDaEIsWUFBWTthQUNiO1NBQ0YsQ0FBQztJQW9JRixDQUFDO0NBQ0Y7QUE5U0Qsb0NBOFNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtyZWRzaGlmdC1kYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9yZWRzaGlmdC1kYXRhLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgUmVkc2hpZnREYXRhIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAncmVkc2hpZnQtZGF0YSc7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGV4ZWN1dGUgbXVsdGlwbGUgcXVlcmllcyB1bmRlciBhIHNpbmdsZSBjb25uZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQmF0Y2hFeGVjdXRlU3RhdGVtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0JhdGNoRXhlY3V0ZVN0YXRlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQmF0Y2hFeGVjdXRlU3RhdGVtZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY2FuY2VsIGEgcnVubmluZyBxdWVyeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmU3RhdGVtZW50T3duZXJJYW1Vc2VyaWQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DYW5jZWxTdGF0ZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ2FuY2VsU3RhdGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDYW5jZWxTdGF0ZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhIHN0YXRlbWVudCBleGVjdXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmU3RhdGVtZW50T3duZXJJYW1Vc2VyaWQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN0YXRlbWVudC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVN0YXRlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdGF0ZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSBtZXRhZGF0YSBhYm91dCBhIHBhcnRpY3VsYXIgdGFibGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlVGFibGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVUYWJsZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGV4ZWN1dGUgYSBxdWVyeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0V4ZWN1dGVTdGF0ZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRXhlY3V0ZVN0YXRlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRXhlY3V0ZVN0YXRlbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBzdGFnaW5nIGJ1Y2tldCBsb2NhdGlvbiBmb3IgYSBnaXZlbiBtYW5hZ2VkIHdvcmtncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U3RhZ2luZ0J1Y2tldExvY2F0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFN0YWdpbmdCdWNrZXRMb2NhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U3RhZ2luZ0J1Y2tldExvY2F0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZmV0Y2ggdGhlIHJlc3VsdCBvZiBhIHF1ZXJ5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlN0YXRlbWVudE93bmVySWFtVXNlcmlkKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U3RhdGVtZW50UmVzdWx0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFN0YXRlbWVudFJlc3VsdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U3RhdGVtZW50UmVzdWx0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBkYXRhYmFzZXMgZm9yIGEgZ2l2ZW4gY2x1c3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdERhdGFiYXNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0RGF0YWJhc2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0RGF0YWJhc2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBzY2hlbWFzIGZvciBhIGdpdmVuIGNsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RTY2hlbWFzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RTY2hlbWFzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0U2NoZW1hcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3Qgc2Vzc2lvbnMgZm9yIGEgZ2l2ZW4gcHJpbmNpcGFsXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlNlc3Npb25Pd25lcklhbVVzZXJpZCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RTZXNzaW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U2Vzc2lvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTZXNzaW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgcXVlcmllcyBmb3IgYSBnaXZlbiBwcmluY2lwYWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmU3RhdGVtZW50T3duZXJJYW1Vc2VyaWQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0U3RhdGVtZW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U3RhdGVtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFN0YXRlbWVudHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRhYmxlcyBmb3IgYSBnaXZlbiBjbHVzdGVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFibGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWJsZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWJsZXMnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0JhdGNoRXhlY3V0ZVN0YXRlbWVudCcsXG4gICAgICAnQ2FuY2VsU3RhdGVtZW50JyxcbiAgICAgICdFeGVjdXRlU3RhdGVtZW50J1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0Rlc2NyaWJlU3RhdGVtZW50JyxcbiAgICAgICdEZXNjcmliZVRhYmxlJyxcbiAgICAgICdHZXRTdGFnaW5nQnVja2V0TG9jYXRpb24nLFxuICAgICAgJ0dldFN0YXRlbWVudFJlc3VsdCcsXG4gICAgICAnTGlzdERhdGFiYXNlcycsXG4gICAgICAnTGlzdFNjaGVtYXMnXG4gICAgXSxcbiAgICBMaXN0OiBbXG4gICAgICAnTGlzdFNlc3Npb25zJyxcbiAgICAgICdMaXN0U3RhdGVtZW50cycsXG4gICAgICAnTGlzdFRhYmxlcydcbiAgICBdXG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGNsdXN0ZXIgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L21nbXQvd29ya2luZy13aXRoLWNsdXN0ZXJzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGNsdXN0ZXJOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGNsdXN0ZXJOYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25DbHVzdGVyKGNsdXN0ZXJOYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06cmVkc2hpZnQ6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OmNsdXN0ZXI6JHsgY2x1c3Rlck5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIG1hbmFnZWQtd29ya2dyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3dvcmtpbmctd2l0aC1zZXJ2ZXJsZXNzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIG1hbmFnZWRXb3JrZ3JvdXBJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBtYW5hZ2VkV29ya2dyb3VwSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKi9cbiAgcHVibGljIG9uTWFuYWdlZFdvcmtncm91cChtYW5hZ2VkV29ya2dyb3VwSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpyZWRzaGlmdC1zZXJ2ZXJsZXNzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTptYW5hZ2VkLXdvcmtncm91cC8keyBtYW5hZ2VkV29ya2dyb3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHdvcmtncm91cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvbWdtdC93b3JraW5nLXdpdGgtc2VydmVybGVzcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSB3b3JrZ3JvdXBJZCAtIElkZW50aWZpZXIgZm9yIHRoZSB3b3JrZ3JvdXBJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uV29ya2dyb3VwKHdvcmtncm91cElkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06cmVkc2hpZnQtc2VydmVybGVzczokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06d29ya2dyb3VwLyR7IHdvcmtncm91cElkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0YWctdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L21nbXQvcmVkc2hpZnQtaWFtLWFjY2Vzcy1jb250cm9sLW92ZXJ2aWV3Lmh0bWwjcmVkc2hpZnQtcG9saWN5LXJlc291cmNlcy5jb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9CYXRjaEV4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0Rlc2NyaWJlVGFibGUoKVxuICAgKiAtIC50b0V4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0xpc3REYXRhYmFzZXMoKVxuICAgKiAtIC50b0xpc3RTY2hlbWFzKClcbiAgICogLSAudG9MaXN0VGFibGVzKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBjbHVzdGVyXG4gICAqIC0gd29ya2dyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGdsdWUgY2F0YWxvZyBhcm5cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3JlZHNoaWZ0LWlhbS1hY2Nlc3MtY29udHJvbC1vdmVydmlldy5odG1sI3JlZHNoaWZ0LXBvbGljeS1yZXNvdXJjZXMuY29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQmF0Y2hFeGVjdXRlU3RhdGVtZW50KClcbiAgICogLSAudG9FeGVjdXRlU3RhdGVtZW50KClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbYXJuIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19BUk4pLiAqKkRlZmF1bHQ6KiogYEFybkxpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZHbHVlQ2F0YWxvZ0Fybih2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgZ2x1ZS1jYXRhbG9nLWFybmAsIHZhbHVlLCBvcGVyYXRvciA/PyAnQXJuTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHNlc3Npb24gb3duZXIgaWFtIHVzZXJpZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L21nbXQvcmVkc2hpZnQtaWFtLWFjY2Vzcy1jb250cm9sLW92ZXJ2aWV3Lmh0bWwjcmVkc2hpZnQtcG9saWN5LXJlc291cmNlcy5jb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9CYXRjaEV4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0V4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0xpc3RTZXNzaW9ucygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmU2Vzc2lvbk93bmVySWFtVXNlcmlkKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBzZXNzaW9uLW93bmVyLWlhbS11c2VyaWRgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSBzdGF0ZW1lbnQgb3duZXIgaWFtIHVzZXJpZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L21nbXQvcmVkc2hpZnQtaWFtLWFjY2Vzcy1jb250cm9sLW92ZXJ2aWV3Lmh0bWwjcmVkc2hpZnQtcG9saWN5LXJlc291cmNlcy5jb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DYW5jZWxTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0Rlc2NyaWJlU3RhdGVtZW50KClcbiAgICogLSAudG9HZXRTdGF0ZW1lbnRSZXN1bHQoKVxuICAgKiAtIC50b0xpc3RTdGF0ZW1lbnRzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZTdGF0ZW1lbnRPd25lcklhbVVzZXJpZCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgc3RhdGVtZW50LW93bmVyLWlhbS11c2VyaWRgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3JlZHNoaWZ0LWRhdGFdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X3JlZHNoaWZ0LWRhdGEuaHRtbCkuXG4gICAqXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm9wcz86IGlhbS5Qb2xpY3lTdGF0ZW1lbnRQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgfVxufVxuIl19