cdk8s-plus-25
Version:
cdk8s+ is a software development framework that provides high level abstractions for authoring Kubernetes applications. cdk8s-plus-25 synthesizes Kubernetes manifests for Kubernetes 1.25.0
174 lines • 24.2 kB
JavaScript
"use strict";
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatefulSetUpdateStrategy = exports.StatefulSet = exports.PodManagementPolicy = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const cdk8s_1 = require("cdk8s");
const container = require("./container");
const k8s = require("./imports/k8s");
const service = require("./service");
const workload = require("./workload");
/**
* Controls how pods are created during initial scale up, when replacing pods on nodes,
* or when scaling down.
*
* The default policy is `OrderedReady`, where pods are created in increasing order
* (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before
* continuing. When scaling down, the pods are removed in the opposite order.
*
* The alternative policy is `Parallel` which will create pods in parallel to match the
* desired scale without waiting, and on scale down will delete all pods at once.
*/
var PodManagementPolicy;
(function (PodManagementPolicy) {
PodManagementPolicy["ORDERED_READY"] = "OrderedReady";
PodManagementPolicy["PARALLEL"] = "Parallel";
})(PodManagementPolicy = exports.PodManagementPolicy || (exports.PodManagementPolicy = {}));
/**
* StatefulSet is the workload API object used to manage stateful applications.
*
* Manages the deployment and scaling of a set of Pods, and provides guarantees
* about the ordering and uniqueness of these Pods.
*
* Like a Deployment, a StatefulSet manages Pods that are based on an identical
* container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity
* for each of their Pods. These pods are created from the same spec, but are not
* interchangeable: each has a persistent identifier that it maintains across any
* rescheduling.
*
* If you want to use storage volumes to provide persistence for your workload, you
* can use a StatefulSet as part of the solution. Although individual Pods in a StatefulSet
* are susceptible to failure, the persistent Pod identifiers make it easier to match existing
* volumes to the new Pods that replace any that have failed.
*
* Using StatefulSets
* ------------------
* StatefulSets are valuable for applications that require one or more of the following.
*
* - Stable, unique network identifiers.
* - Stable, persistent storage.
* - Ordered, graceful deployment and scaling.
* - Ordered, automated rolling updates.
*/
class StatefulSet extends workload.Workload {
constructor(scope, id, props) {
super(scope, id, props);
this.resourceType = 'statefulsets';
this.hasAutoscaler = false;
this.apiObject = new k8s.KubeStatefulSet(this, 'Resource', {
metadata: props.metadata,
spec: cdk8s_1.Lazy.any({ produce: () => this._toKube() }),
});
this.service = props.service ?? this._createHeadlessService();
this.apiObject.addDependency(this.service);
this.replicas = props.replicas;
this.strategy = props.strategy ?? StatefulSetUpdateStrategy.rollingUpdate(),
this.podManagementPolicy = props.podManagementPolicy ?? PodManagementPolicy.ORDERED_READY;
this.minReady = props.minReady ?? cdk8s_1.Duration.seconds(0);
this.service.select(this);
if (this.isolate) {
this.connections.isolate();
}
}
_createHeadlessService() {
const myPorts = container.extractContainerPorts(this);
const myPortNumbers = myPorts.map(p => p.number);
const ports = myPorts.map(p => ({ port: p.number, targetPort: p.number, protocol: p.protocol }));
if (ports.length === 0) {
throw new Error(`Unable to create a service for the stateful set ${this.name}: StatefulSet ports cannot be determined.`);
}
// validate the ports are owned by our containers
for (const port of ports) {
const targetPort = port.targetPort ?? port.port;
if (!myPortNumbers.includes(targetPort)) {
throw new Error(`Unable to expose stateful set ${this.name} via a service: Port ${targetPort} is not exposed by any container`);
}
}
const metadata = { namespace: this.metadata.namespace };
return new service.Service(this, 'Service', {
selector: this,
ports,
metadata,
clusterIP: 'None',
type: service.ServiceType.CLUSTER_IP,
});
}
/**
* @internal
*/
_toKube() {
return {
replicas: this.hasAutoscaler ? undefined : (this.replicas ?? 1),
serviceName: this.service.name,
minReadySeconds: this.minReady.toSeconds(),
template: {
metadata: this.podMetadata.toJson(),
spec: this._toPodSpec(),
},
selector: this._toLabelSelector(),
podManagementPolicy: this.podManagementPolicy,
updateStrategy: this.strategy._toKube(),
};
}
/**
* @see IScalable.markHasAutoscaler()
*/
markHasAutoscaler() {
this.hasAutoscaler = true;
}
/**
* @see IScalable.toScalingTarget()
*/
toScalingTarget() {
return {
kind: this.apiObject.kind,
apiVersion: this.apiObject.apiVersion,
name: this.name,
containers: this.containers,
replicas: this.replicas,
};
}
}
exports.StatefulSet = StatefulSet;
_a = JSII_RTTI_SYMBOL_1;
StatefulSet[_a] = { fqn: "cdk8s-plus-25.StatefulSet", version: "2.22.79" };
/**
* StatefulSet update strategies.
*/
class StatefulSetUpdateStrategy {
constructor(strategy) {
this.strategy = strategy;
}
/**
* The controller will not automatically update the Pods in a StatefulSet.
* Users must manually delete Pods to cause the controller to create new Pods
* that reflect modifications.
*/
static onDelete() {
return new StatefulSetUpdateStrategy({
type: 'OnDelete',
});
}
/**
* The controller will delete and recreate each Pod in the StatefulSet.
* It will proceed in the same order as Pod termination (from the largest ordinal to the smallest),
* updating each Pod one at a time. The Kubernetes control plane waits until an updated
* Pod is Running and Ready prior to updating its predecessor.
*/
static rollingUpdate(options = {}) {
return new StatefulSetUpdateStrategy({
type: 'RollingUpdate',
rollingUpdate: { partition: options.partition ?? 0 },
});
}
/**
* @internal
*/
_toKube() {
return this.strategy;
}
}
exports.StatefulSetUpdateStrategy = StatefulSetUpdateStrategy;
_b = JSII_RTTI_SYMBOL_1;
StatefulSetUpdateStrategy[_b] = { fqn: "cdk8s-plus-25.StatefulSetUpdateStrategy", version: "2.22.79" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGVmdWwtc2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRlZnVsLXNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLGlDQUFrRDtBQUVsRCx5Q0FBeUM7QUFFekMscUNBQXFDO0FBQ3JDLHFDQUFxQztBQUNyQyx1Q0FBdUM7QUFFdkM7Ozs7Ozs7Ozs7R0FVRztBQUNILElBQVksbUJBR1g7QUFIRCxXQUFZLG1CQUFtQjtJQUM3QixxREFBOEIsQ0FBQTtJQUM5Qiw0Q0FBcUIsQ0FBQTtBQUN2QixDQUFDLEVBSFcsbUJBQW1CLEdBQW5CLDJCQUFtQixLQUFuQiwyQkFBbUIsUUFHOUI7QUErQ0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFDSCxNQUFhLFdBQVksU0FBUSxRQUFRLENBQUMsUUFBUTtJQWlDaEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF1QjtRQUMvRCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQVBWLGlCQUFZLEdBQUcsY0FBYyxDQUFDO1FBRXZDLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBTzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDekQsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLElBQUksRUFBRSxZQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1NBQ2xELENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUU5RCxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFM0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSx5QkFBeUIsQ0FBQyxhQUFhLEVBQUU7WUFDM0UsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxtQkFBbUIsSUFBSSxtQkFBbUIsQ0FBQyxhQUFhLENBQUM7UUFDMUYsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJLGdCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXRELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTFCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQzVCO0lBRUgsQ0FBQztJQUVPLHNCQUFzQjtRQUU1QixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEQsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRCxNQUFNLEtBQUssR0FBMEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4SCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELElBQUksQ0FBQyxJQUFJLDJDQUEyQyxDQUFDLENBQUM7U0FDMUg7UUFFRCxpREFBaUQ7UUFDakQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7WUFDeEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2hELElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUN2QyxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxJQUFJLENBQUMsSUFBSSx3QkFBd0IsVUFBVSxrQ0FBa0MsQ0FBQyxDQUFDO2FBQ2pJO1NBQ0Y7UUFFRCxNQUFNLFFBQVEsR0FBUSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzdELE9BQU8sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDMUMsUUFBUSxFQUFFLElBQUk7WUFDZCxLQUFLO1lBQ0wsUUFBUTtZQUNSLFNBQVMsRUFBRSxNQUFNO1lBQ2pCLElBQUksRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLFVBQVU7U0FDckMsQ0FBQyxDQUFDO0lBRUwsQ0FBQztJQUVEOztRQUVJO0lBQ0csT0FBTztRQUNaLE9BQU87WUFDTCxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDO1lBQy9ELFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUk7WUFDOUIsZUFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFO1lBQzFDLFFBQVEsRUFBRTtnQkFDUixRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUU7Z0JBQ25DLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO2FBQ3hCO1lBQ0QsUUFBUSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUNqQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQzdDLGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRTtTQUN4QyxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksaUJBQWlCO1FBQ3RCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7T0FFRztJQUNJLGVBQWU7UUFDcEIsT0FBTztZQUNMLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUk7WUFDekIsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVTtZQUNyQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQ3hCLENBQUM7SUFDSixDQUFDOztBQXpISCxrQ0EwSEM7OztBQXdCRDs7R0FFRztBQUNILE1BQWEseUJBQXlCO0lBMkJwQyxZQUFxQyxRQUF1QztRQUF2QyxhQUFRLEdBQVIsUUFBUSxDQUErQjtJQUFHLENBQUM7SUF6QmhGOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsUUFBUTtRQUNwQixPQUFPLElBQUkseUJBQXlCLENBQUM7WUFDbkMsSUFBSSxFQUFFLFVBQVU7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLGFBQWEsQ0FBQyxVQUF5RCxFQUFFO1FBRXJGLE9BQU8sSUFBSSx5QkFBeUIsQ0FBQztZQUNuQyxJQUFJLEVBQUUsZUFBZTtZQUNyQixhQUFhLEVBQUUsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsSUFBSSxDQUFDLEVBQUU7U0FDckQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUlEOztPQUVHO0lBQ0ksT0FBTztRQUNaLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDOztBQWxDSCw4REFvQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcGlPYmplY3QsIExhenksIER1cmF0aW9uIH0gZnJvbSAnY2RrOHMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyBjb250YWluZXIgZnJvbSAnLi9jb250YWluZXInO1xuaW1wb3J0IHsgSVNjYWxhYmxlLCBTY2FsaW5nVGFyZ2V0IH0gZnJvbSAnLi9ob3Jpem9udGFsLXBvZC1hdXRvc2NhbGVyJztcbmltcG9ydCAqIGFzIGs4cyBmcm9tICcuL2ltcG9ydHMvazhzJztcbmltcG9ydCAqIGFzIHNlcnZpY2UgZnJvbSAnLi9zZXJ2aWNlJztcbmltcG9ydCAqIGFzIHdvcmtsb2FkIGZyb20gJy4vd29ya2xvYWQnO1xuXG4vKipcbiAqIENvbnRyb2xzIGhvdyBwb2RzIGFyZSBjcmVhdGVkIGR1cmluZyBpbml0aWFsIHNjYWxlIHVwLCB3aGVuIHJlcGxhY2luZyBwb2RzIG9uIG5vZGVzLFxuICogb3Igd2hlbiBzY2FsaW5nIGRvd24uXG4gKlxuICogVGhlIGRlZmF1bHQgcG9saWN5IGlzIGBPcmRlcmVkUmVhZHlgLCB3aGVyZSBwb2RzIGFyZSBjcmVhdGVkIGluIGluY3JlYXNpbmcgb3JkZXJcbiAqIChwb2QtMCwgdGhlbiBwb2QtMSwgZXRjKSBhbmQgdGhlIGNvbnRyb2xsZXIgd2lsbCB3YWl0IHVudGlsIGVhY2ggcG9kIGlzIHJlYWR5IGJlZm9yZVxuICogY29udGludWluZy4gV2hlbiBzY2FsaW5nIGRvd24sIHRoZSBwb2RzIGFyZSByZW1vdmVkIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAqXG4gKiBUaGUgYWx0ZXJuYXRpdmUgcG9saWN5IGlzIGBQYXJhbGxlbGAgd2hpY2ggd2lsbCBjcmVhdGUgcG9kcyBpbiBwYXJhbGxlbCB0byBtYXRjaCB0aGVcbiAqIGRlc2lyZWQgc2NhbGUgd2l0aG91dCB3YWl0aW5nLCBhbmQgb24gc2NhbGUgZG93biB3aWxsIGRlbGV0ZSBhbGwgcG9kcyBhdCBvbmNlLlxuICovXG5leHBvcnQgZW51bSBQb2RNYW5hZ2VtZW50UG9saWN5IHtcbiAgT1JERVJFRF9SRUFEWSA9ICdPcmRlcmVkUmVhZHknLFxuICBQQVJBTExFTCA9ICdQYXJhbGxlbCcsXG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgaW5pdGlhbGl6YXRpb24gb2YgYFN0YXRlZnVsU2V0YC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZWZ1bFNldFByb3BzIGV4dGVuZHMgd29ya2xvYWQuV29ya2xvYWRQcm9wcyB7XG4gIC8qKlxuICAgKiBTZXJ2aWNlIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBzdGF0ZWZ1bHNldC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBIG5ldyBoZWFkbGVzcyBzZXJ2aWNlIHdpbGwgYmUgY3JlYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZpY2U/OiBzZXJ2aWNlLlNlcnZpY2U7XG5cbiAgLyoqXG4gICAgKiBOdW1iZXIgb2YgZGVzaXJlZCBwb2RzLlxuICAgICpcbiAgICAqIEBkZWZhdWx0IDFcbiAgICAqL1xuICByZWFkb25seSByZXBsaWNhcz86IG51bWJlcjtcblxuICAvKipcbiAgICAqIFBvZCBtYW5hZ2VtZW50IHBvbGljeSB0byB1c2UgZm9yIHRoaXMgc3RhdGVmdWxzZXQuXG4gICAgKlxuICAgICogQGRlZmF1bHQgUG9kTWFuYWdlbWVudFBvbGljeS5PUkRFUkVEX1JFQURZXG4gICAgKi9cbiAgcmVhZG9ubHkgcG9kTWFuYWdlbWVudFBvbGljeT86IFBvZE1hbmFnZW1lbnRQb2xpY3k7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgU3RhdGVmdWxTZXRVcGRhdGVTdHJhdGVneSB0aGF0IHdpbGwgYmUgZW1wbG95ZWQgdG8gdXBkYXRlIFBvZHMgaW4gdGhlIFN0YXRlZnVsU2V0IHdoZW4gYSByZXZpc2lvbiBpcyBtYWRlIHRvIFRlbXBsYXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFJvbGxpbmdVcGRhdGUgd2l0aCBwYXJ0aXRpb24gc2V0IHRvIDBcbiAgICovXG4gIHJlYWRvbmx5IHN0cmF0ZWd5PzogU3RhdGVmdWxTZXRVcGRhdGVTdHJhdGVneTtcblxuICAvKipcbiAgICogTWluaW11bSBkdXJhdGlvbiBmb3Igd2hpY2ggYSBuZXdseSBjcmVhdGVkIHBvZCBzaG91bGQgYmUgcmVhZHkgd2l0aG91dCBhbnkgb2YgaXRzIGNvbnRhaW5lciBjcmFzaGluZyxcbiAgICogZm9yIGl0IHRvIGJlIGNvbnNpZGVyZWQgYXZhaWxhYmxlLiBaZXJvIG1lYW5zIHRoZSBwb2Qgd2lsbCBiZSBjb25zaWRlcmVkIGF2YWlsYWJsZSBhcyBzb29uIGFzIGl0IGlzIHJlYWR5LlxuICAgKlxuICAgKiBUaGlzIGlzIGFuIGFscGhhIGZpZWxkIGFuZCByZXF1aXJlcyBlbmFibGluZyBTdGF0ZWZ1bFNldE1pblJlYWR5U2Vjb25kcyBmZWF0dXJlIGdhdGUuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvY29uY2VwdHMvd29ya2xvYWRzL2NvbnRyb2xsZXJzL2RlcGxveW1lbnQvI21pbi1yZWFkeS1zZWNvbmRzXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLnNlY29uZHMoMClcbiAgICovXG4gIHJlYWRvbmx5IG1pblJlYWR5PzogRHVyYXRpb247XG5cbn1cblxuLyoqXG4gKiBTdGF0ZWZ1bFNldCBpcyB0aGUgd29ya2xvYWQgQVBJIG9iamVjdCB1c2VkIHRvIG1hbmFnZSBzdGF0ZWZ1bCBhcHBsaWNhdGlvbnMuXG4gKlxuICogTWFuYWdlcyB0aGUgZGVwbG95bWVudCBhbmQgc2NhbGluZyBvZiBhIHNldCBvZiBQb2RzLCBhbmQgcHJvdmlkZXMgZ3VhcmFudGVlc1xuICogYWJvdXQgdGhlIG9yZGVyaW5nIGFuZCB1bmlxdWVuZXNzIG9mIHRoZXNlIFBvZHMuXG4gKlxuICogTGlrZSBhIERlcGxveW1lbnQsIGEgU3RhdGVmdWxTZXQgbWFuYWdlcyBQb2RzIHRoYXQgYXJlIGJhc2VkIG9uIGFuIGlkZW50aWNhbFxuICogY29udGFpbmVyIHNwZWMuIFVubGlrZSBhIERlcGxveW1lbnQsIGEgU3RhdGVmdWxTZXQgbWFpbnRhaW5zIGEgc3RpY2t5IGlkZW50aXR5XG4gKiBmb3IgZWFjaCBvZiB0aGVpciBQb2RzLiBUaGVzZSBwb2RzIGFyZSBjcmVhdGVkIGZyb20gdGhlIHNhbWUgc3BlYywgYnV0IGFyZSBub3RcbiAqIGludGVyY2hhbmdlYWJsZTogZWFjaCBoYXMgYSBwZXJzaXN0ZW50IGlkZW50aWZpZXIgdGhhdCBpdCBtYWludGFpbnMgYWNyb3NzIGFueVxuICogcmVzY2hlZHVsaW5nLlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBzdG9yYWdlIHZvbHVtZXMgdG8gcHJvdmlkZSBwZXJzaXN0ZW5jZSBmb3IgeW91ciB3b3JrbG9hZCwgeW91XG4gKiBjYW4gdXNlIGEgU3RhdGVmdWxTZXQgYXMgcGFydCBvZiB0aGUgc29sdXRpb24uIEFsdGhvdWdoIGluZGl2aWR1YWwgUG9kcyBpbiBhIFN0YXRlZnVsU2V0XG4gKiBhcmUgc3VzY2VwdGlibGUgdG8gZmFpbHVyZSwgdGhlIHBlcnNpc3RlbnQgUG9kIGlkZW50aWZpZXJzIG1ha2UgaXQgZWFzaWVyIHRvIG1hdGNoIGV4aXN0aW5nXG4gKiB2b2x1bWVzIHRvIHRoZSBuZXcgUG9kcyB0aGF0IHJlcGxhY2UgYW55IHRoYXQgaGF2ZSBmYWlsZWQuXG4gKlxuICogVXNpbmcgU3RhdGVmdWxTZXRzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS1cbiAqIFN0YXRlZnVsU2V0cyBhcmUgdmFsdWFibGUgZm9yIGFwcGxpY2F0aW9ucyB0aGF0IHJlcXVpcmUgb25lIG9yIG1vcmUgb2YgdGhlIGZvbGxvd2luZy5cbiAqXG4gKiAtIFN0YWJsZSwgdW5pcXVlIG5ldHdvcmsgaWRlbnRpZmllcnMuXG4gKiAtIFN0YWJsZSwgcGVyc2lzdGVudCBzdG9yYWdlLlxuICogLSBPcmRlcmVkLCBncmFjZWZ1bCBkZXBsb3ltZW50IGFuZCBzY2FsaW5nLlxuICogLSBPcmRlcmVkLCBhdXRvbWF0ZWQgcm9sbGluZyB1cGRhdGVzLlxuICovXG5leHBvcnQgY2xhc3MgU3RhdGVmdWxTZXQgZXh0ZW5kcyB3b3JrbG9hZC5Xb3JrbG9hZCBpbXBsZW1lbnRzIElTY2FsYWJsZSB7XG4gIC8qKlxuICAgICogTnVtYmVyIG9mIGRlc2lyZWQgcG9kcy5cbiAgICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcmVwbGljYXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAgKiBNYW5hZ2VtZW50IHBvbGljeSB0byB1c2UgZm9yIHRoZSBzZXQuXG4gICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBvZE1hbmFnZW1lbnRQb2xpY3k6IFBvZE1hbmFnZW1lbnRQb2xpY3k7XG5cbiAgLyoqXG4gICAqIFRoZSB1cGRhdGUgc3RhcnRlZ3kgb2YgdGhpcyBzdGF0ZWZ1bCBzZXQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3RyYXRlZ3k6IFN0YXRlZnVsU2V0VXBkYXRlU3RyYXRlZ3k7XG5cbiAgLyoqXG4gICAqIE1pbmltdW0gZHVyYXRpb24gZm9yIHdoaWNoIGEgbmV3bHkgY3JlYXRlZCBwb2Qgc2hvdWxkIGJlIHJlYWR5IHdpdGhvdXRcbiAgICogYW55IG9mIGl0cyBjb250YWluZXIgY3Jhc2hpbmcsIGZvciBpdCB0byBiZSBjb25zaWRlcmVkIGF2YWlsYWJsZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtaW5SZWFkeTogRHVyYXRpb247XG5cbiAgLyoqXG4gICAgKiBAc2VlIGJhc2UuUmVzb3VyY2UuYXBpT2JqZWN0XG4gICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFwaU9iamVjdDogQXBpT2JqZWN0O1xuXG4gIHB1YmxpYyByZWFkb25seSByZXNvdXJjZVR5cGUgPSAnc3RhdGVmdWxzZXRzJztcblxuICBwdWJsaWMgaGFzQXV0b3NjYWxlciA9IGZhbHNlO1xuXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlOiBzZXJ2aWNlLlNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0YXRlZnVsU2V0UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMuYXBpT2JqZWN0ID0gbmV3IGs4cy5LdWJlU3RhdGVmdWxTZXQodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgbWV0YWRhdGE6IHByb3BzLm1ldGFkYXRhLFxuICAgICAgc3BlYzogTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLl90b0t1YmUoKSB9KSxcbiAgICB9KTtcbiAgICB0aGlzLnNlcnZpY2UgPSBwcm9wcy5zZXJ2aWNlID8/IHRoaXMuX2NyZWF0ZUhlYWRsZXNzU2VydmljZSgpO1xuXG4gICAgdGhpcy5hcGlPYmplY3QuYWRkRGVwZW5kZW5jeSh0aGlzLnNlcnZpY2UpO1xuXG4gICAgdGhpcy5yZXBsaWNhcyA9IHByb3BzLnJlcGxpY2FzO1xuICAgIHRoaXMuc3RyYXRlZ3kgPSBwcm9wcy5zdHJhdGVneSA/PyBTdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5LnJvbGxpbmdVcGRhdGUoKSxcbiAgICB0aGlzLnBvZE1hbmFnZW1lbnRQb2xpY3kgPSBwcm9wcy5wb2RNYW5hZ2VtZW50UG9saWN5ID8/IFBvZE1hbmFnZW1lbnRQb2xpY3kuT1JERVJFRF9SRUFEWTtcbiAgICB0aGlzLm1pblJlYWR5ID0gcHJvcHMubWluUmVhZHkgPz8gRHVyYXRpb24uc2Vjb25kcygwKTtcblxuICAgIHRoaXMuc2VydmljZS5zZWxlY3QodGhpcyk7XG5cbiAgICBpZiAodGhpcy5pc29sYXRlKSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25zLmlzb2xhdGUoKTtcbiAgICB9XG5cbiAgfVxuXG4gIHByaXZhdGUgX2NyZWF0ZUhlYWRsZXNzU2VydmljZSgpIHtcblxuICAgIGNvbnN0IG15UG9ydHMgPSBjb250YWluZXIuZXh0cmFjdENvbnRhaW5lclBvcnRzKHRoaXMpO1xuICAgIGNvbnN0IG15UG9ydE51bWJlcnMgPSBteVBvcnRzLm1hcChwID0+IHAubnVtYmVyKTtcbiAgICBjb25zdCBwb3J0czogc2VydmljZS5TZXJ2aWNlUG9ydFtdID0gbXlQb3J0cy5tYXAocCA9PiAoeyBwb3J0OiBwLm51bWJlciwgdGFyZ2V0UG9ydDogcC5udW1iZXIsIHByb3RvY29sOiBwLnByb3RvY29sIH0pKTtcbiAgICBpZiAocG9ydHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjcmVhdGUgYSBzZXJ2aWNlIGZvciB0aGUgc3RhdGVmdWwgc2V0ICR7dGhpcy5uYW1lfTogU3RhdGVmdWxTZXQgcG9ydHMgY2Fubm90IGJlIGRldGVybWluZWQuYCk7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgdGhlIHBvcnRzIGFyZSBvd25lZCBieSBvdXIgY29udGFpbmVyc1xuICAgIGZvciAoY29uc3QgcG9ydCBvZiBwb3J0cykge1xuICAgICAgY29uc3QgdGFyZ2V0UG9ydCA9IHBvcnQudGFyZ2V0UG9ydCA/PyBwb3J0LnBvcnQ7XG4gICAgICBpZiAoIW15UG9ydE51bWJlcnMuaW5jbHVkZXModGFyZ2V0UG9ydCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZXhwb3NlIHN0YXRlZnVsIHNldCAke3RoaXMubmFtZX0gdmlhIGEgc2VydmljZTogUG9ydCAke3RhcmdldFBvcnR9IGlzIG5vdCBleHBvc2VkIGJ5IGFueSBjb250YWluZXJgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YTogYW55ID0geyBuYW1lc3BhY2U6IHRoaXMubWV0YWRhdGEubmFtZXNwYWNlIH07XG4gICAgcmV0dXJuIG5ldyBzZXJ2aWNlLlNlcnZpY2UodGhpcywgJ1NlcnZpY2UnLCB7XG4gICAgICBzZWxlY3RvcjogdGhpcyxcbiAgICAgIHBvcnRzLFxuICAgICAgbWV0YWRhdGEsXG4gICAgICBjbHVzdGVySVA6ICdOb25lJyxcbiAgICAgIHR5cGU6IHNlcnZpY2UuU2VydmljZVR5cGUuQ0xVU1RFUl9JUCxcbiAgICB9KTtcblxuICB9XG5cbiAgLyoqXG4gICAgKiBAaW50ZXJuYWxcbiAgICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuU3RhdGVmdWxTZXRTcGVjIHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVwbGljYXM6IHRoaXMuaGFzQXV0b3NjYWxlciA/IHVuZGVmaW5lZCA6ICh0aGlzLnJlcGxpY2FzID8/IDEpLFxuICAgICAgc2VydmljZU5hbWU6IHRoaXMuc2VydmljZS5uYW1lLFxuICAgICAgbWluUmVhZHlTZWNvbmRzOiB0aGlzLm1pblJlYWR5LnRvU2Vjb25kcygpLFxuICAgICAgdGVtcGxhdGU6IHtcbiAgICAgICAgbWV0YWRhdGE6IHRoaXMucG9kTWV0YWRhdGEudG9Kc29uKCksXG4gICAgICAgIHNwZWM6IHRoaXMuX3RvUG9kU3BlYygpLFxuICAgICAgfSxcbiAgICAgIHNlbGVjdG9yOiB0aGlzLl90b0xhYmVsU2VsZWN0b3IoKSxcbiAgICAgIHBvZE1hbmFnZW1lbnRQb2xpY3k6IHRoaXMucG9kTWFuYWdlbWVudFBvbGljeSxcbiAgICAgIHVwZGF0ZVN0cmF0ZWd5OiB0aGlzLnN0cmF0ZWd5Ll90b0t1YmUoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUgSVNjYWxhYmxlLm1hcmtIYXNBdXRvc2NhbGVyKClcbiAgICovXG4gIHB1YmxpYyBtYXJrSGFzQXV0b3NjYWxlcigpIHtcbiAgICB0aGlzLmhhc0F1dG9zY2FsZXIgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzZWUgSVNjYWxhYmxlLnRvU2NhbGluZ1RhcmdldCgpXG4gICAqL1xuICBwdWJsaWMgdG9TY2FsaW5nVGFyZ2V0KCk6IFNjYWxpbmdUYXJnZXQge1xuICAgIHJldHVybiB7XG4gICAgICBraW5kOiB0aGlzLmFwaU9iamVjdC5raW5kLFxuICAgICAgYXBpVmVyc2lvbjogdGhpcy5hcGlPYmplY3QuYXBpVmVyc2lvbixcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgIGNvbnRhaW5lcnM6IHRoaXMuY29udGFpbmVycyxcbiAgICAgIHJlcGxpY2FzOiB0aGlzLnJlcGxpY2FzLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgU3RhdGVmdWxTZXRVcGRhdGVTdHJhdGVneS5yb2xsaW5nVXBkYXRlYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5Um9sbGluZ1VwZGF0ZU9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBJZiBzcGVjaWZpZWQsIGFsbCBQb2RzIHdpdGggYW4gb3JkaW5hbCB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgcGFydGl0aW9uIHdpbGxcbiAgICogYmUgdXBkYXRlZCB3aGVuIHRoZSBTdGF0ZWZ1bFNldCdzIC5zcGVjLnRlbXBsYXRlIGlzIHVwZGF0ZWQuIEFsbCBQb2RzIHdpdGggYW4gb3JkaW5hbCB0aGF0XG4gICAqIGlzIGxlc3MgdGhhbiB0aGUgcGFydGl0aW9uIHdpbGwgbm90IGJlIHVwZGF0ZWQsIGFuZCwgZXZlbiBpZiB0aGV5IGFyZSBkZWxldGVkLCB0aGV5IHdpbGwgYmVcbiAgICogcmVjcmVhdGVkIGF0IHRoZSBwcmV2aW91cyB2ZXJzaW9uLlxuICAgKlxuICAgKiBJZiB0aGUgcGFydGl0aW9uIGlzIGdyZWF0ZXIgdGhhbiByZXBsaWNhcywgdXBkYXRlcyB0byB0aGUgcG9kIHRlbXBsYXRlIHdpbGwgbm90IGJlIHByb3BhZ2F0ZWQgdG8gUG9kcy5cbiAgICogSW4gbW9zdCBjYXNlcyB5b3Ugd2lsbCBub3QgbmVlZCB0byB1c2UgYSBwYXJ0aXRpb24sIGJ1dCB0aGV5IGFyZSB1c2VmdWwgaWYgeW91IHdhbnQgdG8gc3RhZ2UgYW5cbiAgICogdXBkYXRlLCByb2xsIG91dCBhIGNhbmFyeSwgb3IgcGVyZm9ybSBhIHBoYXNlZCByb2xsIG91dC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy93b3JrbG9hZHMvY29udHJvbGxlcnMvc3RhdGVmdWxzZXQvI3BhcnRpdGlvbnNcbiAgICogQGRlZmF1bHQgMFxuICAgKi9cbiAgcmVhZG9ubHkgcGFydGl0aW9uPzogbnVtYmVyO1xuXG59XG5cbi8qKlxuICogU3RhdGVmdWxTZXQgdXBkYXRlIHN0cmF0ZWdpZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5IHtcblxuICAvKipcbiAgICogVGhlIGNvbnRyb2xsZXIgd2lsbCBub3QgYXV0b21hdGljYWxseSB1cGRhdGUgdGhlIFBvZHMgaW4gYSBTdGF0ZWZ1bFNldC5cbiAgICogVXNlcnMgbXVzdCBtYW51YWxseSBkZWxldGUgUG9kcyB0byBjYXVzZSB0aGUgY29udHJvbGxlciB0byBjcmVhdGUgbmV3IFBvZHNcbiAgICogdGhhdCByZWZsZWN0IG1vZGlmaWNhdGlvbnMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG9uRGVsZXRlKCk6IFN0YXRlZnVsU2V0VXBkYXRlU3RyYXRlZ3kge1xuICAgIHJldHVybiBuZXcgU3RhdGVmdWxTZXRVcGRhdGVTdHJhdGVneSh7XG4gICAgICB0eXBlOiAnT25EZWxldGUnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjb250cm9sbGVyIHdpbGwgZGVsZXRlIGFuZCByZWNyZWF0ZSBlYWNoIFBvZCBpbiB0aGUgU3RhdGVmdWxTZXQuXG4gICAqIEl0IHdpbGwgcHJvY2VlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyBQb2QgdGVybWluYXRpb24gKGZyb20gdGhlIGxhcmdlc3Qgb3JkaW5hbCB0byB0aGUgc21hbGxlc3QpLFxuICAgKiB1cGRhdGluZyBlYWNoIFBvZCBvbmUgYXQgYSB0aW1lLiBUaGUgS3ViZXJuZXRlcyBjb250cm9sIHBsYW5lIHdhaXRzIHVudGlsIGFuIHVwZGF0ZWRcbiAgICogUG9kIGlzIFJ1bm5pbmcgYW5kIFJlYWR5IHByaW9yIHRvIHVwZGF0aW5nIGl0cyBwcmVkZWNlc3Nvci5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcm9sbGluZ1VwZGF0ZShvcHRpb25zOiBTdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5Um9sbGluZ1VwZGF0ZU9wdGlvbnMgPSB7fSk6IFN0YXRlZnVsU2V0VXBkYXRlU3RyYXRlZ3kge1xuXG4gICAgcmV0dXJuIG5ldyBTdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5KHtcbiAgICAgIHR5cGU6ICdSb2xsaW5nVXBkYXRlJyxcbiAgICAgIHJvbGxpbmdVcGRhdGU6IHsgcGFydGl0aW9uOiBvcHRpb25zLnBhcnRpdGlvbiA/PyAwIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgc3RyYXRlZ3k6IGs4cy5TdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5KSB7fVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IGs4cy5TdGF0ZWZ1bFNldFVwZGF0ZVN0cmF0ZWd5IHtcbiAgICByZXR1cm4gdGhpcy5zdHJhdGVneTtcbiAgfVxuXG59XG4iXX0=