cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
278 lines • 29.2 kB
JavaScript
"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_amazonredshiftdataapi.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
*
* Possible conditions:
* - .ifSessionOwnerIamUserid()
* - .ifGlueCatalogArn()
*
* 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
*
* Possible conditions:
* - .ifSessionOwnerIamUserid()
* - .ifGlueCatalogArn()
*
* 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 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 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}`);
}
/**
* 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}`);
}
/**
* 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 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()
*
* @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_amazonredshiftdataapi.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'redshift-data';
this.accessLevelList = {
Write: [
'BatchExecuteStatement',
'CancelStatement',
'ExecuteStatement'
],
Read: [
'DescribeStatement',
'DescribeTable',
'GetStagingBucketLocation',
'GetStatementResult',
'ListDatabases',
'ListSchemas'
],
List: [
'ListStatements',
'ListTables'
]
};
}
}
exports.RedshiftData = RedshiftData;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkc2hpZnRkYXRhYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkc2hpZnRkYXRhYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksaUJBQWlCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSwwQkFBMEI7UUFDL0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLG9CQUFvQjtRQUN6QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGFBQWE7UUFDbEIsT0FB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Z0JBQ0osZ0JBQWdCO2dCQUNoQixZQUFZO2FBQ2I7U0FDRixDQUFDO0lBMkhGLENBQUM7Q0FDRjtBQTlSRCxvQ0E4UkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3JlZHNoaWZ0LWRhdGFdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2FtYXpvbnJlZHNoaWZ0ZGF0YWFwaS5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZHNoaWZ0RGF0YSBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ3JlZHNoaWZ0LWRhdGEnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBleGVjdXRlIG11bHRpcGxlIHF1ZXJpZXMgdW5kZXIgYSBzaW5nbGUgY29ubmVjdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmU2Vzc2lvbk93bmVySWFtVXNlcmlkKClcbiAgICogLSAuaWZHbHVlQ2F0YWxvZ0FybigpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0JhdGNoRXhlY3V0ZVN0YXRlbWVudC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9CYXRjaEV4ZWN1dGVTdGF0ZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoRXhlY3V0ZVN0YXRlbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNhbmNlbCBhIHJ1bm5pbmcgcXVlcnlcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlN0YXRlbWVudE93bmVySWFtVXNlcmlkKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2FuY2VsU3RhdGVtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NhbmNlbFN0YXRlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ2FuY2VsU3RhdGVtZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBzdGF0ZW1lbnQgZXhlY3V0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlN0YXRlbWVudE93bmVySWFtVXNlcmlkKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTdGF0ZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdGF0ZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlU3RhdGVtZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgbWV0YWRhdGEgYWJvdXQgYSBwYXJ0aWN1bGFyIHRhYmxlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVRhYmxlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlVGFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlVGFibGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBleGVjdXRlIGEgcXVlcnlcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlNlc3Npb25Pd25lcklhbVVzZXJpZCgpXG4gICAqIC0gLmlmR2x1ZUNhdGFsb2dBcm4oKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FeGVjdXRlU3RhdGVtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0V4ZWN1dGVTdGF0ZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0V4ZWN1dGVTdGF0ZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc3RhZ2luZyBidWNrZXQgbG9jYXRpb24gZm9yIGEgZ2l2ZW4gbWFuYWdlZCB3b3JrZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldFN0YWdpbmdCdWNrZXRMb2NhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdGFnaW5nQnVja2V0TG9jYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFN0YWdpbmdCdWNrZXRMb2NhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGZldGNoIHRoZSByZXN1bHQgb2YgYSBxdWVyeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZTdGF0ZW1lbnRPd25lcklhbVVzZXJpZCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldFN0YXRlbWVudFJlc3VsdC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdGF0ZW1lbnRSZXN1bHQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFN0YXRlbWVudFJlc3VsdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgZGF0YWJhc2VzIGZvciBhIGdpdmVuIGNsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC1kYXRhL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3REYXRhYmFzZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdERhdGFiYXNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdERhdGFiYXNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3Qgc2NoZW1hcyBmb3IgYSBnaXZlbiBjbHVzdGVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQtZGF0YS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0U2NoZW1hcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U2NoZW1hcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFNjaGVtYXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHF1ZXJpZXMgZm9yIGEgZ2l2ZW4gcHJpbmNpcGFsXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlN0YXRlbWVudE93bmVySWFtVXNlcmlkKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFN0YXRlbWVudHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFN0YXRlbWVudHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTdGF0ZW1lbnRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0YWJsZXMgZm9yIGEgZ2l2ZW4gY2x1c3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0LWRhdGEvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhYmxlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFibGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFibGVzJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdCYXRjaEV4ZWN1dGVTdGF0ZW1lbnQnLFxuICAgICAgJ0NhbmNlbFN0YXRlbWVudCcsXG4gICAgICAnRXhlY3V0ZVN0YXRlbWVudCdcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdEZXNjcmliZVN0YXRlbWVudCcsXG4gICAgICAnRGVzY3JpYmVUYWJsZScsXG4gICAgICAnR2V0U3RhZ2luZ0J1Y2tldExvY2F0aW9uJyxcbiAgICAgICdHZXRTdGF0ZW1lbnRSZXN1bHQnLFxuICAgICAgJ0xpc3REYXRhYmFzZXMnLFxuICAgICAgJ0xpc3RTY2hlbWFzJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0xpc3RTdGF0ZW1lbnRzJyxcbiAgICAgICdMaXN0VGFibGVzJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgY2x1c3RlciB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvbWdtdC93b3JraW5nLXdpdGgtY2x1c3RlcnMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gY2x1c3Rlck5hbWUgLSBJZGVudGlmaWVyIGZvciB0aGUgY2x1c3Rlck5hbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkNsdXN0ZXIoY2x1c3Rlck5hbWU6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpyZWRzaGlmdDokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06Y2x1c3RlcjokeyBjbHVzdGVyTmFtZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgd29ya2dyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3dvcmtpbmctd2l0aC1zZXJ2ZXJsZXNzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIHdvcmtncm91cElkIC0gSWRlbnRpZmllciBmb3IgdGhlIHdvcmtncm91cElkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25Xb3JrZ3JvdXAod29ya2dyb3VwSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpyZWRzaGlmdC1zZXJ2ZXJsZXNzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTp3b3JrZ3JvdXAvJHsgd29ya2dyb3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIG1hbmFnZWQtd29ya2dyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3dvcmtpbmctd2l0aC1zZXJ2ZXJsZXNzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIG1hbmFnZWRXb3JrZ3JvdXBJZCAtIElkZW50aWZpZXIgZm9yIHRoZSBtYW5hZ2VkV29ya2dyb3VwSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKi9cbiAgcHVibGljIG9uTWFuYWdlZFdvcmtncm91cChtYW5hZ2VkV29ya2dyb3VwSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpyZWRzaGlmdC1zZXJ2ZXJsZXNzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTptYW5hZ2VkLXdvcmtncm91cC8keyBtYW5hZ2VkV29ya2dyb3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRhZy12YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9yZWRzaGlmdC9sYXRlc3QvbWdtdC9yZWRzaGlmdC1pYW0tYWNjZXNzLWNvbnRyb2wtb3ZlcnZpZXcuaHRtbCNyZWRzaGlmdC1wb2xpY3ktcmVzb3VyY2VzLmNvbmRpdGlvbnNcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBjbHVzdGVyXG4gICAqIC0gd29ya2dyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGdsdWUgY2F0YWxvZyBhcm5cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3JlZHNoaWZ0LWlhbS1hY2Nlc3MtY29udHJvbC1vdmVydmlldy5odG1sI3JlZHNoaWZ0LXBvbGljeS1yZXNvdXJjZXMuY29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQmF0Y2hFeGVjdXRlU3RhdGVtZW50KClcbiAgICogLSAudG9FeGVjdXRlU3RhdGVtZW50KClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbYXJuIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19BUk4pLiAqKkRlZmF1bHQ6KiogYEFybkxpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZHbHVlQ2F0YWxvZ0Fybih2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgZ2x1ZS1jYXRhbG9nLWFybmAsIHZhbHVlLCBvcGVyYXRvciA/PyAnQXJuTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHNlc3Npb24gb3duZXIgaWFtIHVzZXJpZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcmVkc2hpZnQvbGF0ZXN0L21nbXQvcmVkc2hpZnQtaWFtLWFjY2Vzcy1jb250cm9sLW92ZXJ2aWV3Lmh0bWwjcmVkc2hpZnQtcG9saWN5LXJlc291cmNlcy5jb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9CYXRjaEV4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKiAtIC50b0V4ZWN1dGVTdGF0ZW1lbnQoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlNlc3Npb25Pd25lcklhbVVzZXJpZCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgc2Vzc2lvbi1vd25lci1pYW0tdXNlcmlkYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgc3RhdGVtZW50IG93bmVyIGlhbSB1c2VyaWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JlZHNoaWZ0L2xhdGVzdC9tZ210L3JlZHNoaWZ0LWlhbS1hY2Nlc3MtY29udHJvbC1vdmVydmlldy5odG1sI3JlZHNoaWZ0LXBvbGljeS1yZXNvdXJjZXMuY29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ2FuY2VsU3RhdGVtZW50KClcbiAgICogLSAudG9EZXNjcmliZVN0YXRlbWVudCgpXG4gICAqIC0gLnRvR2V0U3RhdGVtZW50UmVzdWx0KClcbiAgICogLSAudG9MaXN0U3RhdGVtZW50cygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmU3RhdGVtZW50T3duZXJJYW1Vc2VyaWQodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYHN0YXRlbWVudC1vd25lci1pYW0tdXNlcmlkYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtyZWRzaGlmdC1kYXRhXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b25yZWRzaGlmdGRhdGFhcGkuaHRtbCkuXG4gICAqXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm9wcz86IGlhbS5Qb2xpY3lTdGF0ZW1lbnRQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgfVxufVxuIl19