UNPKG

@cdklabs/cdk-appflow

Version:

*Note:* this library is currently in technical preview.

151 lines 24.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedshiftConnectorProfile = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const custom_resources_1 = require("aws-cdk-lib/custom-resources"); const type_1 = require("./type"); const appflow_permissions_manager_1 = require("../core/appflow-permissions-manager"); const connector_profile_1 = require("../core/connectors/connector-profile"); class RedshiftConnectorProfile extends connector_profile_1.ConnectorProfileBase { static fromConnectionProfileArn(scope, id, arn) { return this._fromConnectorProfileAttributes(scope, id, { arn, }); } static fromConnectionProfileName(scope, id, name) { return this._fromConnectorProfileAttributes(scope, id, { name, }); } constructor(scope, id, props) { super(scope, id, props, type_1.RedshiftConnectorType.instance); this.tryAddNodeDependency(this, props.cluster); this._location = props.intermediateLocation; } buildConnectorProfileProperties(props) { const properties = props; const redshiftAccessRole = properties.bucketAccessRole ?? this.buildRedshiftAccessRole(this.node.id, properties.cluster, properties.intermediateLocation); const appflowDataApiRole = properties.dataApiRole ?? this.buildAppFlowDataApiRole(this.node.id, properties.cluster, properties.databaseName, properties.basicAuth.username); this.tryAddNodeDependency(this, redshiftAccessRole); this.tryAddNodeDependency(this, appflowDataApiRole); this.tryAddNodeDependency(this, properties.intermediateLocation.bucket); appflow_permissions_manager_1.AppFlowPermissionsManager.instance().grantBucketReadWrite(properties.intermediateLocation.bucket); return { redshift: { bucketName: properties.intermediateLocation.bucket.bucketName, bucketPrefix: properties.intermediateLocation.prefix, roleArn: redshiftAccessRole.roleArn, clusterIdentifier: properties.cluster.clusterName, databaseName: properties.databaseName, dataApiRoleArn: appflowDataApiRole.roleArn, }, }; } buildConnectorProfileCredentials(props) { const properties = props; return { redshift: properties && { username: properties.basicAuth.username, password: properties.basicAuth.password?.unsafeUnwrap(), }, }; } buildRedshiftAccessRole(id, cluster, location) { // see: https://docs.aws.amazon.com/appflow/latest/userguide/security_iam_service-role-policies.html#redshift-access-s3 const role = new aws_iam_1.Role(this.stack, `${id}RedshiftRole`, { assumedBy: new aws_iam_1.ServicePrincipal("redshift.amazonaws.com"), }); location.bucket.grantRead(role, location.prefix ? `${location.prefix}/*` : "*"); const modifierId = `${id}RedshiftRoleAttach`; const modifier = new custom_resources_1.AwsCustomResource(this.stack, modifierId, { onCreate: { service: "Redshift", action: "modifyClusterIamRoles", parameters: { ClusterIdentifier: cluster.clusterName, AddIamRoles: [role.roleArn], }, physicalResourceId: custom_resources_1.PhysicalResourceId.of(modifierId), }, policy: custom_resources_1.AwsCustomResourcePolicy.fromStatements([ new aws_iam_1.PolicyStatement({ actions: ["iam:PassRole"], resources: [role.roleArn], effect: aws_iam_1.Effect.ALLOW, }), new aws_iam_1.PolicyStatement({ actions: ["redshift:ModifyClusterIamRoles"], resources: [ `arn:${aws_cdk_lib_1.Aws.PARTITION}:redshift:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:cluster:${cluster.clusterName}`, ], effect: aws_iam_1.Effect.ALLOW, }), ]), }); this.node.addDependency(modifier); modifier.node.addDependency(cluster); return role; } buildAppFlowDataApiRole(id, cluster, databaseName, username) { // see: https://docs.aws.amazon.com/appflow/latest/userguide/security_iam_service-role-policies.html#access-redshift const role = new aws_iam_1.Role(this.stack, `${id}AppFlowDataApiRole`, { assumedBy: new aws_iam_1.ServicePrincipal("appflow.amazonaws.com"), }); const policy = new aws_iam_1.Policy(this.stack, `${id}AppFlowDataApiRolePolicy`, { roles: [role], statements: [ new aws_iam_1.PolicyStatement({ sid: "DataAPIPermissions", effect: aws_iam_1.Effect.ALLOW, actions: [ "redshift-data:ExecuteStatement", "redshift-data:GetStatementResult", "redshift-data:DescribeStatement", ], resources: ["*"], }), new aws_iam_1.PolicyStatement({ sid: "GetCredentialsForAPIUser", effect: aws_iam_1.Effect.ALLOW, actions: ["redshift:GetClusterCredentials"], resources: [ `arn:aws:redshift:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:dbname:${cluster.clusterName}/${databaseName}`, `arn:aws:redshift:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:dbuser:${cluster.clusterName}/${username ?? "*"}`, ], }), new aws_iam_1.PolicyStatement({ sid: "DenyCreateAPIUser", effect: aws_iam_1.Effect.DENY, actions: ["redshift:CreateClusterUser"], resources: [ `arn:aws:redshift:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:dbuser:${cluster.clusterName}/*`, ], }), new aws_iam_1.PolicyStatement({ sid: "ServiceLinkedRole", effect: aws_iam_1.Effect.ALLOW, actions: ["iam:CreateServiceLinkedRole"], resources: [ `arn:aws:iam::${aws_cdk_lib_1.Aws.ACCOUNT_ID}:role/aws-service-role/redshift-data.amazonaws.com/AWSServiceRoleForRedshift`, ], conditions: { StringLike: { "iam:AWSServiceName": "redshift-data.amazonaws.com", }, }, }), ], }); this.tryAddNodeDependency(this, policy); return role; } } exports.RedshiftConnectorProfile = RedshiftConnectorProfile; _a = JSII_RTTI_SYMBOL_1; RedshiftConnectorProfile[_a] = { fqn: "@cdklabs/cdk-appflow.RedshiftConnectorProfile", version: "0.2.3" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWRzaGlmdC9wcm9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBS0EsNkNBQStDO0FBRS9DLGlEQU82QjtBQUM3QixtRUFJc0M7QUFFdEMsaUNBQStDO0FBRS9DLHFGQUFnRjtBQUNoRiw0RUFHOEM7QUFpQzlDLE1BQWEsd0JBQXlCLFNBQVEsd0NBQW9CO0lBQ3pELE1BQU0sQ0FBQyx3QkFBd0IsQ0FDcEMsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEdBQVc7UUFFWCxPQUFPLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ3JELEdBQUc7U0FDSixDQUE2QixDQUFDO0lBQ2pDLENBQUM7SUFFTSxNQUFNLENBQUMseUJBQXlCLENBQ3JDLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixJQUFZO1FBRVosT0FBTyxJQUFJLENBQUMsK0JBQStCLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNyRCxJQUFJO1NBQ0wsQ0FBNkIsQ0FBQztJQUNqQyxDQUFDO0lBT0QsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBb0M7UUFFcEMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLDRCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixDQUFDO0lBQzlDLENBQUM7SUFFUywrQkFBK0IsQ0FDdkMsS0FBNEI7UUFFNUIsTUFBTSxVQUFVLEdBQUcsS0FBc0MsQ0FBQztRQUUxRCxNQUFNLGtCQUFrQixHQUN0QixVQUFVLENBQUMsZ0JBQWdCO1lBQzNCLElBQUksQ0FBQyx1QkFBdUIsQ0FDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxF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RSxNQUFNLENBQUMsQ0FBQztRQUV4QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7O0FBdE1ILDREQXVNQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4qL1xuaW1wb3J0IHsgSUNsdXN0ZXIgfSBmcm9tIFwiQGF3cy1jZGsvYXdzLXJlZHNoaWZ0LWFscGhhXCI7XG5pbXBvcnQgeyBBd3MsIFNlY3JldFZhbHVlIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBDZm5Db25uZWN0b3JQcm9maWxlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1hcHBmbG93XCI7XG5pbXBvcnQge1xuICBFZmZlY3QsXG4gIElSb2xlLFxuICBQb2xpY3ksXG4gIFBvbGljeVN0YXRlbWVudCxcbiAgUm9sZSxcbiAgU2VydmljZVByaW5jaXBhbCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7XG4gIEF3c0N1c3RvbVJlc291cmNlLFxuICBBd3NDdXN0b21SZXNvdXJjZVBvbGljeSxcbiAgUGh5c2ljYWxSZXNvdXJjZUlkLFxufSBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IFJlZHNoaWZ0Q29ubmVjdG9yVHlwZSB9IGZyb20gXCIuL3R5cGVcIjtcbmltcG9ydCB7IFMzTG9jYXRpb24gfSBmcm9tIFwiLi4vY29yZVwiO1xuaW1wb3J0IHsgQXBwRmxvd1Blcm1pc3Npb25zTWFuYWdlciB9IGZyb20gXCIuLi9jb3JlL2FwcGZsb3ctcGVybWlzc2lvbnMtbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgQ29ubmVjdG9yUHJvZmlsZUJhc2UsXG4gIENvbm5lY3RvclByb2ZpbGVQcm9wcyxcbn0gZnJvbSBcIi4uL2NvcmUvY29ubmVjdG9ycy9jb25uZWN0b3ItcHJvZmlsZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlZHNoaWZ0Q29ubmVjdG9yQmFzaWNDcmVkZW50aWFscyB7XG4gIHJlYWRvbmx5IHVzZXJuYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBwYXNzd29yZD86IFNlY3JldFZhbHVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlZHNoaWZ0Q29ubmVjdG9yUHJvZmlsZVByb3BzIGV4dGVuZHMgQ29ubmVjdG9yUHJvZmlsZVByb3BzIHtcbiAgcmVhZG9ubHkgYmFzaWNBdXRoOiBSZWRzaGlmdENvbm5lY3RvckJhc2ljQ3JlZGVudGlhbHM7XG4gIC8qKlxuICAgKiBBbiBpbnRlcm1lZGlhdGUgbG9jYXRpb24gZm9yIHRoZSBkYXRhIHJldHJpZXZlZCBmcm9tIHRoZSBmbG93IHNvdXJjZSB0aGF0IHdpbGwgYmUgZnVydGhlciB0cmFuc2ZlcnJlZCB0byB0aGUgUmVkc2hmaXQgZGF0YWJhc2VcbiAgICovXG4gIHJlYWRvbmx5IGludGVybWVkaWF0ZUxvY2F0aW9uOiBTM0xvY2F0aW9uO1xuICAvKipcbiAgICogVGhlIFJlZHNoaWZ0IGNsdXN0ZXIgdG8gdXNlIHRoaXMgY29ubmVjdG9yIHByb2ZpbGUgd2l0aFxuICAgKi9cbiAgcmVhZG9ubHkgY2x1c3RlcjogSUNsdXN0ZXI7XG4gIC8qKlxuICAgKiBBbiBJQU0gUm9sZSB0aGF0IEFwcEZsb3cgd2lsbCBhc3N1bWUgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgUmVkc2hpZnQgY2x1c3RlcidzIERhdGEgQVBJXG4gICAqXG4gICAqIEBkZWZhdWx0IGF1dG9nZW5lcmF0ZWQgSUFNIHJvbGVcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFBcGlSb2xlPzogSVJvbGU7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2Ugd2hpY2ggdGhlIFJlZHNoaWZ0Q29ubmVjdG9yUHJvZmlsZSB3aWxsIGJlIHdvcmtpbmcgd2l0aFxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbiBJQU0gUm9sZSB0aGF0IHRoZSBSZWRzaGlmdCBjbHVzdGVyIHdpbGwgYXNzdW1lIHRvIGdldCBkYXRhIGZyb20gdGhlIGludGVybWllZGlhdGUgUzMgQnVja2V0XG4gICAqL1xuICByZWFkb25seSBidWNrZXRBY2Nlc3NSb2xlPzogSVJvbGU7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWRzaGlmdENvbm5lY3RvclByb2ZpbGUgZXh0ZW5kcyBDb25uZWN0b3JQcm9maWxlQmFzZSB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbUNvbm5lY3Rpb25Qcm9maWxlQXJuKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBhcm46IHN0cmluZyxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Zyb21Db25uZWN0b3JQcm9maWxlQXR0cmlidXRlcyhzY29wZSwgaWQsIHtcbiAgICAgIGFybixcbiAgICB9KSBhcyBSZWRzaGlmdENvbm5lY3RvclByb2ZpbGU7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZyb21Db25uZWN0aW9uUHJvZmlsZU5hbWUoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Zyb21Db25uZWN0b3JQcm9maWxlQXR0cmlidXRlcyhzY29wZSwgaWQsIHtcbiAgICAgIG5hbWUsXG4gICAgfSkgYXMgUmVkc2hpZnRDb25uZWN0b3JQcm9maWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IF9sb2NhdGlvbjogUzNMb2NhdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFJlZHNoaWZ0Q29ubmVjdG9yUHJvZmlsZVByb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzLCBSZWRzaGlmdENvbm5lY3RvclR5cGUuaW5zdGFuY2UpO1xuICAgIHRoaXMudHJ5QWRkTm9kZURlcGVuZGVuY3kodGhpcywgcHJvcHMuY2x1c3Rlcik7XG4gICAgdGhpcy5fbG9jYXRpb24gPSBwcm9wcy5pbnRlcm1lZGlhdGVMb2NhdGlvbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZENvbm5lY3RvclByb2ZpbGVQcm9wZXJ0aWVzKFxuICAgIHByb3BzOiBDb25uZWN0b3JQcm9maWxlUHJvcHMsXG4gICk6IENmbkNvbm5lY3RvclByb2ZpbGUuQ29ubmVjdG9yUHJvZmlsZVByb3BlcnRpZXNQcm9wZXJ0eSB7XG4gICAgY29uc3QgcHJvcGVydGllcyA9IHByb3BzIGFzIFJlZHNoaWZ0Q29ubmVjdG9yUHJvZmlsZVByb3BzO1xuXG4gICAgY29uc3QgcmVkc2hpZnRBY2Nlc3NSb2xlID1cbiAgICAgIHByb3BlcnRpZXMuYnVja2V0QWNjZXNzUm9sZSA/P1xuICAgICAgdGhpcy5idWlsZFJlZHNoaWZ0QWNjZXNzUm9sZShcbiAgICAgICAgdGhpcy5ub2RlLmlkLFxuICAgICAgICBwcm9wZXJ0aWVzLmNsdXN0ZXIsXG4gICAgICAgIHByb3BlcnRpZXMuaW50ZXJtZWRpYXRlTG9jYXRpb24sXG4gICAgICApO1xuXG4gICAgY29uc3QgYXBwZmxvd0RhdGFBcGlSb2xlID1cbiAgICAgIHByb3BlcnRpZXMuZGF0YUFwaVJvbGUgPz9cbiAgICAgIHRoaXMuYnVpbGRBcHBGbG93RGF0YUFwaVJvbGUoXG4gICAgICAgIHRoaXMubm9kZS5pZCxcbiAgICAgICAgcHJvcGVydGllcy5jbHVzdGVyLFxuICAgICAgICBwcm9wZXJ0aWVzLmRhdGFiYXNlTmFtZSxcbiAgICAgICAgcHJvcGVydGllcy5iYXNpY0F1dGgudXNlcm5hbWUsXG4gICAgICApO1xuXG4gICAgdGhpcy50cnlBZGROb2RlRGVwZW5kZW5jeSh0aGlzLCByZWRzaGlmdEFjY2Vzc1JvbGUpO1xuICAgIHRoaXMudHJ5QWRkTm9kZURlcGVuZGVuY3kodGhpcywgYXBwZmxvd0RhdGFBcGlSb2xlKTtcbiAgICB0aGlzLnRyeUFkZE5vZGVEZXBlbmRlbmN5KHRoaXMsIHByb3BlcnRpZXMuaW50ZXJtZWRpYXRlTG9jYXRpb24uYnVja2V0KTtcbiAgICBBcHBGbG93UGVybWlzc2lvbnNNYW5hZ2VyLmluc3RhbmNlKCkuZ3JhbnRCdWNrZXRSZWFkV3JpdGUoXG4gICAgICBwcm9wZXJ0aWVzLmludGVybWVkaWF0ZUxvY2F0aW9uLmJ1Y2tldCxcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlZHNoaWZ0OiB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IHByb3BlcnRpZXMuaW50ZXJtZWRpYXRlTG9jYXRpb24uYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgIGJ1Y2tldFByZWZpeDogcHJvcGVydGllcy5pbnRlcm1lZGlhdGVMb2NhdGlvbi5wcmVmaXgsXG4gICAgICAgIHJvbGVBcm46IHJlZHNoaWZ0QWNjZXNzUm9sZS5yb2xlQXJuLFxuICAgICAgICBjbHVzdGVySWRlbnRpZmllcjogcHJvcGVydGllcy5jbHVzdGVyLmNsdXN0ZXJOYW1lLFxuICAgICAgICBkYXRhYmFzZU5hbWU6IHByb3BlcnRpZXMuZGF0YWJhc2VOYW1lLFxuICAgICAgICBkYXRhQXBpUm9sZUFybjogYXBwZmxvd0RhdGFBcGlSb2xlLnJvbGVBcm4sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYnVpbGRDb25uZWN0b3JQcm9maWxlQ3JlZGVudGlhbHMoXG4gICAgcHJvcHM6IENvbm5lY3RvclByb2ZpbGVQcm9wcyxcbiAgKTogQ2ZuQ29ubmVjdG9yUHJvZmlsZS5Db25uZWN0b3JQcm9maWxlQ3JlZGVudGlhbHNQcm9wZXJ0eSB7XG4gICAgY29uc3QgcHJvcGVydGllcyA9IHByb3BzIGFzIFJlZHNoaWZ0Q29ubmVjdG9yUHJvZmlsZVByb3BzO1xuICAgIHJldHVybiB7XG4gICAgICByZWRzaGlmdDogcHJvcGVydGllcyAmJiB7XG4gICAgICAgIHVzZXJuYW1lOiBwcm9wZXJ0aWVzLmJhc2ljQXV0aC51c2VybmFtZSxcbiAgICAgICAgcGFzc3dvcmQ6IHByb3BlcnRpZXMuYmFzaWNBdXRoLnBhc3N3b3JkPy51bnNhZmVVbndyYXAoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRSZWRzaGlmdEFjY2Vzc1JvbGUoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBjbHVzdGVyOiBJQ2x1c3RlcixcbiAgICBsb2NhdGlvbjogUzNMb2NhdGlvbixcbiAgKTogSVJvbGUge1xuICAgIC8vIHNlZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwcGZsb3cvbGF0ZXN0L3VzZXJndWlkZS9zZWN1cml0eV9pYW1fc2VydmljZS1yb2xlLXBvbGljaWVzLmh0bWwjcmVkc2hpZnQtYWNjZXNzLXMzXG4gICAgY29uc3Qgcm9sZSA9IG5ldyBSb2xlKHRoaXMuc3RhY2ssIGAke2lkfVJlZHNoaWZ0Um9sZWAsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoXCJyZWRzaGlmdC5hbWF6b25hd3MuY29tXCIpLFxuICAgIH0pO1xuXG4gICAgbG9jYXRpb24uYnVja2V0LmdyYW50UmVhZChcbiAgICAgIHJvbGUsXG4gICAgICBsb2NhdGlvbi5wcmVmaXggPyBgJHtsb2NhdGlvbi5wcmVmaXh9LypgIDogXCIqXCIsXG4gICAgKTtcblxuICAgIGNvbnN0IG1vZGlmaWVySWQgPSBgJHtpZH1SZWRzaGlmdFJvbGVBdHRhY2hgO1xuXG4gICAgY29uc3QgbW9kaWZpZXIgPSBuZXcgQXdzQ3VzdG9tUmVzb3VyY2UodGhpcy5zdGFjaywgbW9kaWZpZXJJZCwge1xuICAgICAgb25DcmVhdGU6IHtcbiAgICAgICAgc2VydmljZTogXCJSZWRzaGlmdFwiLFxuICAgICAgICBhY3Rpb246IFwibW9kaWZ5Q2x1c3RlcklhbVJvbGVzXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICBDbHVzdGVySWRlbnRpZmllcjogY2x1c3Rlci5jbHVzdGVyTmFtZSxcbiAgICAgICAgICBBZGRJYW1Sb2xlczogW3JvbGUucm9sZUFybl0sXG4gICAgICAgIH0sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogUGh5c2ljYWxSZXNvdXJjZUlkLm9mKG1vZGlmaWVySWQpLFxuICAgICAgfSxcbiAgICAgIHBvbGljeTogQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVN0YXRlbWVudHMoW1xuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJpYW06UGFzc1JvbGVcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbcm9sZS5yb2xlQXJuXSxcbiAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgfSksXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIGFjdGlvbnM6IFtcInJlZHNoaWZ0Ok1vZGlmeUNsdXN0ZXJJYW1Sb2xlc1wiXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICAgIGBhcm46JHtBd3MuUEFSVElUSU9OfTpyZWRzaGlmdDoke0F3cy5SRUdJT059OiR7QXdzLkFDQ09VTlRfSUR9OmNsdXN0ZXI6JHtjbHVzdGVyLmNsdXN0ZXJOYW1lfWAsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgfSksXG4gICAgICBdKSxcbiAgICB9KTtcblxuICAgIHRoaXMubm9kZS5hZGREZXBlbmRlbmN5KG1vZGlmaWVyKTtcbiAgICBtb2RpZmllci5ub2RlLmFkZERlcGVuZGVuY3koY2x1c3Rlcik7XG5cbiAgICByZXR1cm4gcm9sZTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRBcHBGbG93RGF0YUFwaVJvbGUoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBjbHVzdGVyOiBJQ2x1c3RlcixcbiAgICBkYXRhYmFzZU5hbWU6IHN0cmluZyxcbiAgICB1c2VybmFtZT86IHN0cmluZyxcbiAgKTogSVJvbGUge1xuICAgIC8vIHNlZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FwcGZsb3cvbGF0ZXN0L3VzZXJndWlkZS9zZWN1cml0eV9pYW1fc2VydmljZS1yb2xlLXBvbGljaWVzLmh0bWwjYWNjZXNzLXJlZHNoaWZ0XG4gICAgY29uc3Qgcm9sZSA9IG5ldyBSb2xlKHRoaXMuc3RhY2ssIGAke2lkfUFwcEZsb3dEYXRhQXBpUm9sZWAsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoXCJhcHBmbG93LmFtYXpvbmF3cy5jb21cIiksXG4gICAgfSk7XG5cbiAgICBjb25zdCBwb2xpY3kgPSBuZXcgUG9saWN5KHRoaXMuc3RhY2ssIGAke2lkfUFwcEZsb3dEYXRhQXBpUm9sZVBvbGljeWAsIHtcbiAgICAgIHJvbGVzOiBbcm9sZV0sXG4gICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIHNpZDogXCJEYXRhQVBJUGVybWlzc2lvbnNcIixcbiAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICBcInJlZHNoaWZ0LWRhdGE6RXhlY3V0ZVN0YXRlbWVudFwiLFxuICAgICAgICAgICAgXCJyZWRzaGlmdC1kYXRhOkdldFN0YXRlbWVudFJlc3VsdFwiLFxuICAgICAgICAgICAgXCJyZWRzaGlmdC1kYXRhOkRlc2NyaWJlU3RhdGVtZW50XCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgIH0pLFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBzaWQ6IFwiR2V0Q3JlZGVudGlhbHNGb3JBUElVc2VyXCIsXG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgICAgYWN0aW9uczogW1wicmVkc2hpZnQ6R2V0Q2x1c3RlckNyZWRlbnRpYWxzXCJdLFxuICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgYGFybjphd3M6cmVkc2hpZnQ6JHtBd3MuUkVHSU9OfToke0F3cy5BQ0NPVU5UX0lEfTpkYm5hbWU6JHtjbHVzdGVyLmNsdXN0ZXJOYW1lfS8ke2RhdGFiYXNlTmFtZX1gLFxuICAgICAgICAgICAgYGFybjphd3M6cmVkc2hpZnQ6JHtBd3MuUkVHSU9OfToke0F3cy5BQ0NPVU5UX0lEfTpkYnVzZXI6JHtjbHVzdGVyLmNsdXN0ZXJOYW1lfS8ke3VzZXJuYW1lID8/IFwiKlwifWAsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSksXG4gICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgIHNpZDogXCJEZW55Q3JlYXRlQVBJVXNlclwiLFxuICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkRFTlksXG4gICAgICAgICAgYWN0aW9uczogW1wicmVkc2hpZnQ6Q3JlYXRlQ2x1c3RlclVzZXJcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICBgYXJuOmF3czpyZWRzaGlmdDoke0F3cy5SRUdJT059OiR7QXdzLkFDQ09VTlRfSUR9OmRidXNlcjoke2NsdXN0ZXIuY2x1c3Rlck5hbWV9LypgLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pLFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBzaWQ6IFwiU2VydmljZUxpbmtlZFJvbGVcIixcbiAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICBhY3Rpb25zOiBbXCJpYW06Q3JlYXRlU2VydmljZUxpbmtlZFJvbGVcIl0sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICBgYXJuOmF3czppYW06OiR7QXdzLkFDQ09VTlRfSUR9OnJvbGUvYXdzLXNlcnZpY2Utcm9sZS9yZWRzaGlmdC1kYXRhLmFtYXpvbmF3cy5jb20vQVdTU2VydmljZVJvbGVGb3JSZWRzaGlmdGAsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgICAgIFwiaWFtOkFXU1NlcnZpY2VOYW1lXCI6IFwicmVkc2hpZnQtZGF0YS5hbWF6b25hd3MuY29tXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIHRoaXMudHJ5QWRkTm9kZURlcGVuZGVuY3kodGhpcywgcG9saWN5KTtcblxuICAgIHJldHVybiByb2xlO1xuICB9XG59XG4iXX0=