@cdklabs/multi-az-observability 0.0.1-alpha.3 → 0.0.1-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.jsii +374 -147
  2. package/API.md +292 -100
  3. package/README.md +21 -14
  4. package/cdk.json +1 -1
  5. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.d.ts +7 -7
  6. package/lib/alarmsandrules/AvailabilityAndLatencyAlarmsAndRules.js +35 -35
  7. package/lib/alarmsandrules/BaseOperationRegionalAlarmsAndRules.js +2 -2
  8. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.d.ts +6 -15
  9. package/lib/alarmsandrules/BaseOperationZonalAlarmsAndRules.js +2 -10
  10. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.d.ts +11 -3
  11. package/lib/alarmsandrules/CanaryOperationZonalAlarmsAndRules.js +24 -13
  12. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.d.ts +0 -8
  13. package/lib/alarmsandrules/IBaseOperationZonalAlarmsAndRules.js +1 -1
  14. package/lib/alarmsandrules/IOperationAlarmsAndRules.d.ts +19 -27
  15. package/lib/alarmsandrules/IOperationAlarmsAndRules.js +1 -1
  16. package/lib/alarmsandrules/IServerSideOperationRegionalAlarmsAndRules.js +1 -1
  17. package/lib/alarmsandrules/IServiceAlarmsAndRules.d.ts +0 -8
  18. package/lib/alarmsandrules/IServiceAlarmsAndRules.js +1 -1
  19. package/lib/alarmsandrules/OperationAlarmsAndRules.d.ts +14 -22
  20. package/lib/alarmsandrules/OperationAlarmsAndRules.js +51 -71
  21. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.d.ts +5 -5
  22. package/lib/alarmsandrules/ServerSideOperationRegionalAlarmsAndRules.js +2 -3
  23. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.d.ts +21 -13
  24. package/lib/alarmsandrules/ServerSideOperationZonalAlarmsAndRules.js +43 -29
  25. package/lib/alarmsandrules/ServiceAlarmsAndRules.d.ts +0 -2
  26. package/lib/alarmsandrules/ServiceAlarmsAndRules.js +61 -39
  27. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.d.ts +6 -44
  28. package/lib/alarmsandrules/props/BaseOperationZonalAlarmsAndRulesProps.js +1 -1
  29. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.d.ts +28 -7
  30. package/lib/alarmsandrules/props/OperationAlarmsAndRulesProps.js +1 -1
  31. package/lib/azmapper/AvailabilityZoneMapper.js +4 -3
  32. package/lib/basic_observability/BasicServiceDashboard.d.ts +0 -3
  33. package/lib/basic_observability/BasicServiceDashboard.js +24 -112
  34. package/lib/basic_observability/BasicServiceMultiAZObservability.d.ts +8 -9
  35. package/lib/basic_observability/BasicServiceMultiAZObservability.js +100 -312
  36. package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.d.ts +50 -0
  37. package/lib/basic_observability/props/ApplicationLoadBalancerDetectionProps.js +3 -0
  38. package/lib/basic_observability/props/BasicServiceDashboardProps.d.ts +27 -13
  39. package/lib/basic_observability/props/BasicServiceDashboardProps.js +1 -1
  40. package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.d.ts +10 -38
  41. package/lib/basic_observability/props/BasicServiceMultiAZObservabilityProps.js +1 -1
  42. package/lib/basic_observability/props/NatGatewayDetectionProps.d.ts +31 -0
  43. package/lib/basic_observability/props/NatGatewayDetectionProps.js +3 -0
  44. package/lib/canaries/CanaryFunction.js +7 -6
  45. package/lib/canaries/src/canary.zip +0 -0
  46. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.d.ts +2 -6
  47. package/lib/dashboards/OperationAvailabilityAndLatencyDashboard.js +440 -506
  48. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.d.ts +0 -1
  49. package/lib/dashboards/ServiceAvailabilityAndLatencyDashboard.js +56 -113
  50. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.d.ts +3 -66
  51. package/lib/dashboards/props/OperationAvailabilityAndLatencyDashboardProps.js +1 -1
  52. package/lib/dashboards/props/OperationAvailabilityWidgetProps.d.ts +7 -2
  53. package/lib/dashboards/props/OperationAvailabilityWidgetProps.js +1 -1
  54. package/lib/dashboards/props/OperationLatencyWidgetProps.d.ts +7 -2
  55. package/lib/dashboards/props/OperationLatencyWidgetProps.js +1 -1
  56. package/lib/index.d.ts +5 -0
  57. package/lib/index.js +8 -2
  58. package/lib/metrics/ApplicationLoadBalancerMetrics.d.ts +72 -4
  59. package/lib/metrics/ApplicationLoadBalancerMetrics.js +671 -33
  60. package/lib/metrics/AvailabilityAndLatencyMetrics.d.ts +23 -0
  61. package/lib/metrics/AvailabilityAndLatencyMetrics.js +117 -24
  62. package/lib/metrics/NatGatewayMetrics.d.ts +113 -0
  63. package/lib/metrics/NatGatewayMetrics.js +357 -0
  64. package/lib/metrics/RegionalLatencyMetrics.d.ts +1 -1
  65. package/lib/metrics/RegionalLatencyMetrics.js +27 -20
  66. package/lib/metrics/ZonalAvailabilityMetrics.d.ts +2 -8
  67. package/lib/metrics/ZonalAvailabilityMetrics.js +10 -25
  68. package/lib/metrics/ZonalLatencyMetrics.d.ts +2 -1
  69. package/lib/metrics/ZonalLatencyMetrics.js +33 -23
  70. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.d.ts +4 -0
  71. package/lib/metrics/props/AvailabilityAndLatencyMetricProps.js +1 -1
  72. package/lib/metrics/props/LatencyMetricProps.d.ts +6 -0
  73. package/lib/metrics/props/LatencyMetricProps.js +1 -1
  74. package/lib/metrics/props/ZonalAvailabilityMetricProps.d.ts +4 -0
  75. package/lib/metrics/props/ZonalAvailabilityMetricProps.js +1 -1
  76. package/lib/metrics/props/ZonalLatencyMetricProps.d.ts +4 -0
  77. package/lib/metrics/props/ZonalLatencyMetricProps.js +1 -1
  78. package/lib/monitoring/src/monitoring-layer.zip +0 -0
  79. package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.d.ts +10 -0
  80. package/lib/outlier-detection/ApplicationLoadBalancerAvailabilityOutlierAlgorithm.js +15 -0
  81. package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.d.ts +18 -0
  82. package/lib/outlier-detection/ApplicationLoadBalancerLatencyOutlierAlgorithm.js +23 -0
  83. package/lib/outlier-detection/OutlierDetectionFunction.js +6 -5
  84. package/lib/outlier-detection/PacketLossOutlierAlgorithm.d.ts +10 -0
  85. package/lib/outlier-detection/PacketLossOutlierAlgorithm.js +15 -0
  86. package/lib/outlier-detection/src/outlier-detection.zip +0 -0
  87. package/lib/outlier-detection/src/scipy-layer.zip +0 -0
  88. package/lib/services/CanaryMetrics.js +1 -1
  89. package/lib/services/CanaryTestMetricsOverride.js +1 -1
  90. package/lib/services/ContributorInsightRuleDetails.js +1 -1
  91. package/lib/services/InstrumentedServiceMultiAZObservability.d.ts +10 -0
  92. package/lib/services/InstrumentedServiceMultiAZObservability.js +188 -194
  93. package/lib/services/Operation.js +1 -1
  94. package/lib/services/OperationMetricDetails.js +1 -1
  95. package/lib/services/Service.js +1 -1
  96. package/lib/services/ServiceMetricDetails.js +1 -1
  97. package/lib/services/props/MetricDimensions.js +1 -1
  98. package/lib/utilities/MetricsHelper.d.ts +15 -10
  99. package/lib/utilities/MetricsHelper.js +19 -11
  100. package/package.json +8 -8
@@ -1,6 +1,8 @@
1
1
  import { IMetric } from 'aws-cdk-lib/aws-cloudwatch';
2
2
  import { AvailabilityMetricProps } from './props/AvailabilityMetricProps';
3
3
  import { LatencyMetricProps } from './props/LatencyMetricProps';
4
+ import { ZonalAvailabilityMetricProps } from './props/ZonalAvailabilityMetricProps';
5
+ import { ZonalLatencyMetricProps } from './props/ZonalLatencyMetricProps';
4
6
  /**
5
7
  * Class for creating availability and latency metrics that can be used in alarms and graphs
6
8
  */
@@ -14,6 +16,15 @@ export declare class AvailabilityAndLatencyMetrics {
14
16
  static createAvailabilityMetric(props: AvailabilityMetricProps, dimensions: {
15
17
  [key: string]: string;
16
18
  }): IMetric;
19
+ /**
20
+ * Creates availability metrics for a specific AZ
21
+ * @param props
22
+ * @param dimensions
23
+ * @returns
24
+ */
25
+ static createZonalAvailabilityMetric(props: ZonalAvailabilityMetricProps, dimensions: {
26
+ [key: string]: string;
27
+ }): IMetric;
17
28
  /**
18
29
  * General purpose method to create latency metrics, the reason this creates an array of metrics while the
19
30
  * equivalent availability metric method doesn't is because in availability, we can just sum the count of different
@@ -28,6 +39,15 @@ export declare class AvailabilityAndLatencyMetrics {
28
39
  static createLatencyMetrics(props: LatencyMetricProps, dimensions: {
29
40
  [key: string]: string;
30
41
  }): IMetric[];
42
+ /**
43
+ * Creates a latency metric with the provided name
44
+ * @param props
45
+ * @param dimensions
46
+ * @returns
47
+ */
48
+ static createLatencyMetric(props: LatencyMetricProps, dimensions: {
49
+ [key: string]: string;
50
+ }): IMetric;
31
51
  /**
32
52
  * Takes all of the success or failure latency metric names and creates an average of those
33
53
  * names, if there's only 1 name, it just returns that metric
@@ -47,4 +67,7 @@ export declare class AvailabilityAndLatencyMetrics {
47
67
  static createLatencyCountMetric(props: LatencyMetricProps, dimensions: {
48
68
  [key: string]: string;
49
69
  }): IMetric;
70
+ static createZonalLatencyCountMetric(props: ZonalLatencyMetricProps, dimensions: {
71
+ [key: string]: string;
72
+ }): IMetric;
50
73
  }
@@ -17,21 +17,13 @@ class AvailabilityAndLatencyMetrics {
17
17
  * @returns
18
18
  */
19
19
  static createAvailabilityMetric(props, dimensions) {
20
- let counter = 0;
21
- let key = '';
22
20
  let usingMetrics = {};
23
21
  let successKeys = [];
24
22
  let faultKeys = [];
25
23
  if (props.metricDetails.successMetricNames !== undefined &&
26
24
  props.metricType != AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT) {
27
25
  props.metricDetails.successMetricNames.forEach((successMetric) => {
28
- let keyPrefix = (props.keyPrefix === undefined || props.keyPrefix == ''
29
- ? ''
30
- : props.keyPrefix.toLowerCase() + '_') +
31
- props.metricDetails.operationName.toLowerCase() +
32
- '_' +
33
- successMetric.toLowerCase();
34
- key = keyPrefix + '_' + counter++;
26
+ let key = `${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${successMetric.toLowerCase()}`;
35
27
  successKeys.push(key);
36
28
  usingMetrics[key] = new aws_cloudwatch_1.Metric({
37
29
  namespace: props.metricDetails.metricNamespace,
@@ -47,13 +39,75 @@ class AvailabilityAndLatencyMetrics {
47
39
  if (props.metricDetails.faultMetricNames !== undefined &&
48
40
  props.metricType != AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT) {
49
41
  props.metricDetails.faultMetricNames.forEach((faultMetric) => {
50
- let keyPrefix = (props.keyPrefix === undefined || props.keyPrefix == ''
51
- ? ''
52
- : props.keyPrefix.toLowerCase() + '_') +
53
- props.metricDetails.operationName.toLowerCase() +
54
- '_' +
55
- faultMetric.toLowerCase();
56
- key = keyPrefix + '_' + counter++;
42
+ let key = `${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${faultMetric.toLowerCase()}`;
43
+ faultKeys.push(key);
44
+ usingMetrics[key] = new aws_cloudwatch_1.Metric({
45
+ namespace: props.metricDetails.metricNamespace,
46
+ metricName: faultMetric,
47
+ unit: props.metricDetails.unit,
48
+ period: props.metricDetails.period,
49
+ statistic: props.metricDetails.alarmStatistic,
50
+ dimensionsMap: dimensions,
51
+ label: faultMetric,
52
+ });
53
+ });
54
+ }
55
+ let expression = '';
56
+ switch (props.metricType) {
57
+ case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_RATE:
58
+ expression = `((${successKeys.join('+')}) / (${successKeys.join('+')}+${faultKeys.join('+')})) * 100`;
59
+ break;
60
+ case AvailabilityMetricType_1.AvailabilityMetricType.REQUEST_COUNT:
61
+ expression = `${successKeys.join('+')}+${faultKeys.join('+')}`;
62
+ break;
63
+ case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT:
64
+ expression = `(${faultKeys.join('+')})`;
65
+ break;
66
+ case AvailabilityMetricType_1.AvailabilityMetricType.FAULT_RATE:
67
+ expression = `((${faultKeys.join('+')}) / (${successKeys.join('+')}+${faultKeys.join('+')})) * 100`;
68
+ break;
69
+ case AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT:
70
+ expression = `(${successKeys.join('+')})`;
71
+ break;
72
+ }
73
+ return new aws_cloudwatch_1.MathExpression({
74
+ expression: expression,
75
+ label: props.label,
76
+ period: props.metricDetails.period,
77
+ usingMetrics: usingMetrics,
78
+ color: props.color
79
+ });
80
+ }
81
+ /**
82
+ * Creates availability metrics for a specific AZ
83
+ * @param props
84
+ * @param dimensions
85
+ * @returns
86
+ */
87
+ static createZonalAvailabilityMetric(props, dimensions) {
88
+ let usingMetrics = {};
89
+ let successKeys = [];
90
+ let faultKeys = [];
91
+ if (props.metricDetails.successMetricNames !== undefined &&
92
+ props.metricType != AvailabilityMetricType_1.AvailabilityMetricType.FAULT_COUNT) {
93
+ props.metricDetails.successMetricNames.forEach((successMetric) => {
94
+ let key = `${props.availabilityZone.substring(props.availabilityZone.length - 1)}_${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${successMetric.toLowerCase()}`;
95
+ successKeys.push(key);
96
+ usingMetrics[key] = new aws_cloudwatch_1.Metric({
97
+ namespace: props.metricDetails.metricNamespace,
98
+ metricName: successMetric,
99
+ unit: props.metricDetails.unit,
100
+ period: props.metricDetails.period,
101
+ statistic: props.metricDetails.alarmStatistic,
102
+ dimensionsMap: dimensions,
103
+ label: successMetric,
104
+ });
105
+ });
106
+ }
107
+ if (props.metricDetails.faultMetricNames !== undefined &&
108
+ props.metricType != AvailabilityMetricType_1.AvailabilityMetricType.SUCCESS_COUNT) {
109
+ props.metricDetails.faultMetricNames.forEach((faultMetric) => {
110
+ let key = `${props.availabilityZone.substring(props.availabilityZone.length - 1)}_${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${faultMetric.toLowerCase()}`;
57
111
  faultKeys.push(key);
58
112
  usingMetrics[key] = new aws_cloudwatch_1.Metric({
59
113
  namespace: props.metricDetails.metricNamespace,
@@ -89,6 +143,7 @@ class AvailabilityAndLatencyMetrics {
89
143
  label: props.label,
90
144
  period: props.metricDetails.period,
91
145
  usingMetrics: usingMetrics,
146
+ color: props.color
92
147
  });
93
148
  }
94
149
  /**
@@ -123,6 +178,27 @@ class AvailabilityAndLatencyMetrics {
123
178
  label: props.label,
124
179
  }));
125
180
  }
181
+ /**
182
+ * Creates a latency metric with the provided name
183
+ * @param props
184
+ * @param dimensions
185
+ * @returns
186
+ */
187
+ static createLatencyMetric(props, dimensions) {
188
+ if (!(props.metricName)) {
189
+ throw new Error("You must provide a metric name.");
190
+ }
191
+ return new aws_cloudwatch_1.Metric({
192
+ metricName: props.metricName,
193
+ namespace: props.metricDetails.metricNamespace,
194
+ unit: props.metricDetails.unit,
195
+ period: props.metricDetails.period,
196
+ statistic: props.statistic,
197
+ dimensionsMap: dimensions,
198
+ label: props.label,
199
+ color: props.color
200
+ });
201
+ }
126
202
  /**
127
203
  * Takes all of the success or failure latency metric names and creates an average of those
128
204
  * names, if there's only 1 name, it just returns that metric
@@ -150,6 +226,7 @@ class AvailabilityAndLatencyMetrics {
150
226
  label: props.label,
151
227
  period: props.metricDetails.period,
152
228
  usingMetrics: usingMetrics,
229
+ color: props.color
153
230
  });
154
231
  }
155
232
  }
@@ -168,22 +245,38 @@ class AvailabilityAndLatencyMetrics {
168
245
  else {
169
246
  let usingMetrics = {};
170
247
  latencyMetrics.forEach((metric, index) => {
171
- let keyPrefix = (props.keyPrefix === undefined || props.keyPrefix == ''
172
- ? ''
173
- : props.keyPrefix.toLowerCase() + '_') +
174
- props.metricDetails.operationName.toLowerCase() +
175
- '_' +
176
- props.metricType.toString().toLowerCase();
177
- usingMetrics[keyPrefix + index] = metric;
248
+ let key = `${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${index}`;
249
+ usingMetrics[key] = metric;
250
+ });
251
+ return new aws_cloudwatch_1.MathExpression({
252
+ expression: Object.keys(usingMetrics).join('+'),
253
+ label: props.label,
254
+ period: props.metricDetails.period,
255
+ usingMetrics: usingMetrics,
256
+ color: props.color
257
+ });
258
+ }
259
+ }
260
+ static createZonalLatencyCountMetric(props, dimensions) {
261
+ let latencyMetrics = AvailabilityAndLatencyMetrics.createLatencyMetrics(props, dimensions);
262
+ if (latencyMetrics.length == 1) {
263
+ return latencyMetrics[0];
264
+ }
265
+ else {
266
+ let usingMetrics = {};
267
+ latencyMetrics.forEach((metric, index) => {
268
+ let key = `${props.availabilityZone.substring(props.availabilityZone.length - 1)}_${props.metricDetails.operationName.toLowerCase()}_${props.metricType.toString().toLowerCase()}_${index}`;
269
+ usingMetrics[key] = metric;
178
270
  });
179
271
  return new aws_cloudwatch_1.MathExpression({
180
272
  expression: Object.keys(usingMetrics).join('+'),
181
273
  label: props.label,
182
274
  period: props.metricDetails.period,
183
275
  usingMetrics: usingMetrics,
276
+ color: props.color
184
277
  });
185
278
  }
186
279
  }
187
280
  }
188
281
  exports.AvailabilityAndLatencyMetrics = AvailabilityAndLatencyMetrics;
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0cmljcy9BdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBcUU7QUFDckUsc0NBQXNDO0FBQ3RDLCtEQUE2RTtBQUc3RSxnRkFBNkU7QUFDN0Usc0VBQW1FO0FBRW5FOztHQUVHO0FBQ0gsTUFBYSw2QkFBNkI7SUFFeEM7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsd0JBQXdCLENBQzdCLEtBQThCLEVBQzlCLFVBQXFDO1FBRXJDLElBQUksT0FBTyxHQUFXLENBQUMsQ0FBQztRQUN4QixJQUFJLEdBQUcsR0FBVyxFQUFFLENBQUM7UUFFckIsSUFBSSxZQUFZLEdBQStCLEVBQUUsQ0FBQztRQUVsRCxJQUFJLFdBQVcsR0FBYSxFQUFFLENBQUM7UUFDL0IsSUFBSSxTQUFTLEdBQWEsRUFBRSxDQUFDO1FBRTdCLElBQ0UsS0FBSyxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsS0FBSyxTQUFTO1lBQ3BELEtBQUssQ0FBQyxVQUFVLElBQUksK0NBQXNCLENBQUMsV0FBVyxFQUN0RCxDQUFDO1lBQ0QsS0FBSyxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQzVDLENBQUMsYUFBcUIsRUFBRSxFQUFFO2dCQUN4QixJQUFJLFNBQVMsR0FDWCxDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxTQUFTLElBQUksRUFBRTtvQkFDckQsQ0FBQyxDQUFDLEVBQUU7b0JBQ0osQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsR0FBRyxDQUFDO29CQUN4QyxLQUFLLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUU7b0JBQy9DLEdBQUc7b0JBQ0gsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dC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eEIsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFDL0MsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO2dCQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFNO2dCQUNsQyxZQUFZLEVBQUUsWUFBWTthQUMzQixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBak9ELHNFQWlPQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbmltcG9ydCB7IElNZXRyaWMsIE1ldHJpYywgTWF0aEV4cHJlc3Npb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyB9IGZyb20gJy4vcHJvcHMvQXZhaWxhYmlsaXR5TWV0cmljUHJvcHMnO1xuaW1wb3J0IHsgTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSAnLi9wcm9wcy9MYXRlbmN5TWV0cmljUHJvcHMnO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5TWV0cmljVHlwZSB9IGZyb20gJy4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlJztcbmltcG9ydCB7IExhdGVuY3lNZXRyaWNUeXBlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL0xhdGVuY3lNZXRyaWNUeXBlJztcblxuLyoqXG4gKiBDbGFzcyBmb3IgY3JlYXRpbmcgYXZhaWxhYmlsaXR5IGFuZCBsYXRlbmN5IG1ldHJpY3MgdGhhdCBjYW4gYmUgdXNlZCBpbiBhbGFybXMgYW5kIGdyYXBoc1xuICovXG5leHBvcnQgY2xhc3MgQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3Mge1xuXG4gIC8qKlxuICAgKiBHZW5lcmFsIHB1cnBvc2UgbWV0aG9kIHRvIGNyZWF0ZSBhdmFpbGFiaWxpdHkgbWV0cmljc1xuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHBhcmFtIGRpbWVuc2lvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgcHJvcHM6IEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWMge1xuICAgIGxldCBjb3VudGVyOiBudW1iZXIgPSAwO1xuICAgIGxldCBrZXk6IHN0cmluZyA9ICcnO1xuXG4gICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgIGxldCBzdWNjZXNzS2V5czogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgZmF1bHRLZXlzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgaWYgKFxuICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5zdWNjZXNzTWV0cmljTmFtZXMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgcHJvcHMubWV0cmljVHlwZSAhPSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UXG4gICAgKSB7XG4gICAgICBwcm9wcy5tZXRyaWNEZXRhaWxzLnN1Y2Nlc3NNZXRyaWNOYW1lcy5mb3JFYWNoKFxuICAgICAgICAoc3VjY2Vzc01ldHJpYzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgbGV0IGtleVByZWZpeCA9XG4gICAgICAgICAgICAocHJvcHMua2V5UHJlZml4ID09PSB1bmRlZmluZWQgfHwgcHJvcHMua2V5UHJlZml4ID09ICcnXG4gICAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgICAgOiBwcm9wcy5rZXlQcmVmaXgudG9Mb3dlckNhc2UoKSArICdfJykgK1xuICAgICAgICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkgK1xuICAgICAgICAgICAgJ18nICtcbiAgICAgICAgICAgIHN1Y2Nlc3NNZXRyaWMudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAgIGtleSA9IGtleVByZWZpeCArICdfJyArIGNvdW50ZXIrKztcbiAgICAgICAgICBzdWNjZXNzS2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgICB1c2luZ01ldHJpY3Nba2V5XSA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgICAgbmFtZXNwYWNlOiBwcm9wcy5tZXRyaWNEZXRhaWxzLm1ldHJpY05hbWVzcGFjZSxcbiAgICAgICAgICAgIG1ldHJpY05hbWU6IHN1Y2Nlc3NNZXRyaWMsXG4gICAgICAgICAgICB1bml0OiBwcm9wcy5tZXRyaWNEZXRhaWxzLnVuaXQsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5tZXRyaWNEZXRhaWxzLmFsYXJtU3RhdGlzdGljLFxuICAgICAgICAgICAgZGltZW5zaW9uc01hcDogZGltZW5zaW9ucyxcbiAgICAgICAgICAgIGxhYmVsOiBzdWNjZXNzTWV0cmljLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcm9wcy5tZXRyaWNEZXRhaWxzLmZhdWx0TWV0cmljTmFtZXMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgcHJvcHMubWV0cmljVHlwZSAhPSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlRcbiAgICApIHtcbiAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMuZmF1bHRNZXRyaWNOYW1lcy5mb3JFYWNoKChmYXVsdE1ldHJpYykgPT4ge1xuICAgICAgICBsZXQga2V5UHJlZml4ID1cbiAgICAgICAgICAocHJvcHMua2V5UHJlZml4ID09PSB1bmRlZmluZWQgfHwgcHJvcHMua2V5UHJlZml4ID09ICcnXG4gICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICA6IHByb3BzLmtleVByZWZpeC50b0xvd2VyQ2FzZSgpICsgJ18nKSArXG4gICAgICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkgK1xuICAgICAgICAgICdfJyArXG4gICAgICAgICAgZmF1bHRNZXRyaWMudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICBrZXkgPSBrZXlQcmVmaXggKyAnXycgKyBjb3VudGVyKys7XG4gICAgICAgIGZhdWx0S2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgdXNpbmdNZXRyaWNzW2tleV0gPSBuZXcgTWV0cmljKHtcbiAgICAgICAgICBuYW1lc3BhY2U6IHByb3BzLm1ldHJpY0RldGFpbHMubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICAgIG1ldHJpY05hbWU6IGZhdWx0TWV0cmljLFxuICAgICAgICAgIHVuaXQ6IHByb3BzLm1ldHJpY0RldGFpbHMudW5pdCxcbiAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgIHN0YXRpc3RpYzogcHJvcHMubWV0cmljRGV0YWlscy5hbGFybVN0YXRpc3RpYyxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOiBkaW1lbnNpb25zLFxuICAgICAgICAgIGxhYmVsOiBmYXVsdE1ldHJpYyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBsZXQgZXhwcmVzc2lvbjogc3RyaW5nID0gJyc7XG5cbiAgICBzd2l0Y2ggKHByb3BzLm1ldHJpY1R5cGUpIHtcbiAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX1JBVEU6XG4gICAgICAgIGV4cHJlc3Npb24gPSBgKCgke3N1Y2Nlc3NLZXlzLmpvaW4oJysnKX0pIC8gKCR7c3VjY2Vzc0tleXMuam9pbignKycpfSske2ZhdWx0S2V5cy5qb2luKCcrJyl9KSkgKiAxMDBgO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5SRVFVRVNUX0NPVU5UOlxuICAgICAgICBleHByZXNzaW9uID0gYCR7c3VjY2Vzc0tleXMuam9pbignKycpfSske2ZhdWx0S2V5cy5qb2luKCcrJyl9YDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlQ6XG4gICAgICAgIGV4cHJlc3Npb24gPSBgKCR7ZmF1bHRLZXlzLmpvaW4oJysnKX0pYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfUkFURTpcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAoKCR7ZmF1bHRLZXlzLmpvaW4oJysnKX0pIC8gKCR7c3VjY2Vzc0tleXMuam9pbignKycpfSske2ZhdWx0S2V5cy5qb2luKCcrJyl9KSkgKiAxMDBgO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5TVUNDRVNTX0NPVU5UOlxuICAgICAgICBleHByZXNzaW9uID0gYCgke3N1Y2Nlc3NLZXlzLmpvaW4oJysnKX0pYDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICBleHByZXNzaW9uOiBleHByZXNzaW9uLFxuICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgcGVyaW9kOiBwcm9wcy5tZXRyaWNEZXRhaWxzLnBlcmlvZCxcbiAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYWwgcHVycG9zZSBtZXRob2QgdG8gY3JlYXRlIGxhdGVuY3kgbWV0cmljcywgdGhlIHJlYXNvbiB0aGlzIGNyZWF0ZXMgYW4gYXJyYXkgb2YgbWV0cmljcyB3aGlsZSB0aGVcbiAgICogZXF1aXZhbGVudCBhdmFpbGFiaWxpdHkgbWV0cmljIG1ldGhvZCBkb2Vzbid0IGlzIGJlY2F1c2UgaW4gYXZhaWxhYmlsaXR5LCB3ZSBjYW4ganVzdCBzdW0gdGhlIGNvdW50IG9mIGRpZmZlcmVudFxuICAgKiBtZXRyaWMgbmFtZXMgd2hpbGUgZm9yIGxhdGVuY3kgd2UgY2FuJ3Qgc3VtIHRoZSBjb3VudCBiZWNhdXNlIHRoYXQncyBub3Qgd2hhdCdzIGJlaW5nIG1lYXN1cmVkLiBJdCBhbGxvd3MgdGhlXG4gICAqIGNhbGxlciB0byBkZWNpZGUgaWYgdGhleSBvbmx5IHdhbnQgdG8gdGFrZSB0aGUgZmlyc3QgbmFtZSwgb3IgYXZlcmFnZSBhbGwgb2YgdGhlIG5hbWVzXG4gICAqIChsaWtlIFN1Y2Nlc3NMYXRlbmN5IGFuZCBCaWdJdGVtU3VjY2Vzc0xhdGVuY3kpLlxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHBhcmFtIGRpbWVuc2lvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVMYXRlbmN5TWV0cmljcyhcbiAgICBwcm9wczogTGF0ZW5jeU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWNbXSB7XG4gICAgbGV0IG5hbWVzOiBzdHJpbmdbXTtcblxuICAgIHN3aXRjaCAocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgZGVmYXVsdDpcbiAgICAgIGNhc2UgTGF0ZW5jeU1ldHJpY1R5cGUuU1VDQ0VTU19MQVRFTkNZOlxuICAgICAgICBuYW1lcyA9IHByb3BzLm1ldHJpY0RldGFpbHMuc3VjY2Vzc01ldHJpY05hbWVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTGF0ZW5jeU1ldHJpY1R5cGUuRkFVTFRfTEFURU5DWTpcbiAgICAgICAgbmFtZXMgPSBwcm9wcy5tZXRyaWNEZXRhaWxzLmZhdWx0TWV0cmljTmFtZXM7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBuYW1lcy5tYXAoXG4gICAgICAoeCkgPT5cbiAgICAgICAgbmV3IE1ldHJpYyh7XG4gICAgICAgICAgbWV0cmljTmFtZTogeCxcbiAgICAgICAgICBuYW1lc3BhY2U6IHByb3BzLm1ldHJpY0RldGFpbHMubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICAgIHVuaXQ6IHByb3BzLm1ldHJpY0RldGFpbHMudW5pdCxcbiAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgIHN0YXRpc3RpYzogcHJvcHMuc3RhdGlzdGljLFxuICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IGRpbWVuc2lvbnMsXG4gICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRha2VzIGFsbCBvZiB0aGUgc3VjY2VzcyBvciBmYWlsdXJlIGxhdGVuY3kgbWV0cmljIG5hbWVzIGFuZCBjcmVhdGVzIGFuIGF2ZXJhZ2Ugb2YgdGhvc2VcbiAgICogbmFtZXMsIGlmIHRoZXJlJ3Mgb25seSAxIG5hbWUsIGl0IGp1c3QgcmV0dXJucyB0aGF0IG1ldHJpY1xuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHBhcmFtIGRpbWVuc2lvbnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVBdmVyYWdlTGF0ZW5jeU1ldHJpYyhcbiAgICBwcm9wczogTGF0ZW5jeU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWMge1xuICAgIGxldCBsYXRlbmN5TWV0cmljczogSU1ldHJpY1tdID1cbiAgICAgIEF2YWlsYWJpbGl0eUFuZExhdGVuY3lNZXRyaWNzLmNyZWF0ZUxhdGVuY3lNZXRyaWNzKHByb3BzLCBkaW1lbnNpb25zKTtcblxuICAgIGlmIChsYXRlbmN5TWV0cmljcy5sZW5ndGggPT0gMSkge1xuICAgICAgcmV0dXJuIGxhdGVuY3lNZXRyaWNzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICBsYXRlbmN5TWV0cmljcy5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGtleVByZWZpeDogc3RyaW5nID1cbiAgICAgICAgICAocHJvcHMua2V5UHJlZml4ID09PSB1bmRlZmluZWQgfHwgcHJvcHMua2V5UHJlZml4ID09ICcnXG4gICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICA6IHByb3BzLmtleVByZWZpeC50b0xvd2VyQ2FzZSgpICsgJ18nKSArXG4gICAgICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkgK1xuICAgICAgICAgICdfJyArXG4gICAgICAgICAgcHJvcHMubWV0cmljVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgdXNpbmdNZXRyaWNzW2tleVByZWZpeCArIGluZGV4XSA9IG1ldHJpYztcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgZXhwcmVzc2lvbjogYCgke09iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpfSkvJHtPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmxlbmd0aH1gLFxuICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgIHBlcmlvZDogcHJvcHMubWV0cmljRGV0YWlscy5wZXJpb2QsXG4gICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb3VudCBvZiBoaWdoIGxhdGVuY3kgbWV0cmljcyBmb3IgZWl0aGVyIFN1Y2Nlc3NMYXRlbmN5IG9yIEZhdWx0TGF0ZW5jeSwgd2lsbCB0b3RhbFxuICAgKiB0aGUgY291bnQgb2YgcmVxdWVzdHMgdGhhdCBleGNlZWQgYSB0aHJlc2hvbGQgeW91IGRlZmluZSBpbiB5b3VyIHN0YXRpc3RpYywgbGlrZSBUQygyMDA6KSBhY3Jvc3NcbiAgICogYWxsIG1ldHJpYyBuYW1lcyB0aGF0IGFyZSBwYXJ0IG9mIGVpdGhlciBTdWNjZXNzIG9yIEZhdWx0IGxhdGVuY3kuXG4gICAqIEBwYXJhbSBwcm9wc1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUxhdGVuY3lDb3VudE1ldHJpYyhcbiAgICBwcm9wczogTGF0ZW5jeU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWMge1xuICAgIGxldCBsYXRlbmN5TWV0cmljczogSU1ldHJpY1tdID1cbiAgICAgIEF2YWlsYWJpbGl0eUFuZExhdGVuY3lNZXRyaWNzLmNyZWF0ZUxhdGVuY3lNZXRyaWNzKHByb3BzLCBkaW1lbnNpb25zKTtcblxuICAgIGlmIChsYXRlbmN5TWV0cmljcy5sZW5ndGggPT0gMSkge1xuICAgICAgcmV0dXJuIGxhdGVuY3lNZXRyaWNzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgICBsYXRlbmN5TWV0cmljcy5mb3JFYWNoKChtZXRyaWM6IElNZXRyaWMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbGV0IGtleVByZWZpeDogc3RyaW5nID1cbiAgICAgICAgICAocHJvcHMua2V5UHJlZml4ID09PSB1bmRlZmluZWQgfHwgcHJvcHMua2V5UHJlZml4ID09ICcnXG4gICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICA6IHByb3BzLmtleVByZWZpeC50b0xvd2VyQ2FzZSgpICsgJ18nKSArXG4gICAgICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCkgK1xuICAgICAgICAgICdfJyArXG4gICAgICAgICAgcHJvcHMubWV0cmljVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgdXNpbmdNZXRyaWNzW2tleVByZWZpeCArIGluZGV4XSA9IG1ldHJpYztcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKCcrJyksXG4gICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgcGVyaW9kOiBwcm9wcy5tZXRyaWNEZXRhaWxzLnBlcmlvZCxcbiAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
282
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0cmljcy9BdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFBcUU7QUFDckUsc0NBQXNDO0FBQ3RDLCtEQUE2RTtBQUc3RSxnRkFBNkU7QUFDN0Usc0VBQW1FO0FBSW5FOztHQUVHO0FBQ0gsTUFBYSw2QkFBNkI7SUFFeEM7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsd0JBQXdCLENBQzdCLEtBQThCLEVBQzlCLFVBQXFDO1FBRXJDLElBQUksWUFBWSxHQUErQixFQUFFLENBQUM7UUFFbEQsSUFBSSxXQUFXLEdBQWEsRUFBRSxDQUFDO1FBQy9CLElBQUksU0FBUyxHQUFhLEVBQUUsQ0FBQztRQUU3QixJQUNFLEtBQUssQ0FBQyxhQUFhLENBQUMsa0JBQWtCLEtBQUssU0FBUztZQUNwRCxLQUFLLENBQUMsVUFBVSxJQUFJLCtDQUFzQixDQUFDLFdBQVcsRUFDdEQsQ0FBQztZQUNELEtBQUssQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBcUIsRUFBRSxFQUFFO2dCQUNyRSxJQUFJLEdBQUcsR0FBVyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLFdBQVcsRUFBRSxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsV0FBVyxFQUFFLElBQUksYUFBYSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBRW5KLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBRXRCLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLHVCQUFNLENBQUM7b0JBQzdCLFNBQVMsRUFBRSxLQUFLLENBQUMsYUFBYSxDQUFDLGVBQWU7b0JBQzlDLFVBQVUsRUFBRSxhQUFhO29CQUN6QixJQUFJLEVB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RUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsTUFBTSxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUMsTUFBTTtnQkFDbEMsWUFBWSxFQUFFLFlBQVk7Z0JBQzFCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSzthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBdlZELHNFQXVWQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbmltcG9ydCB7IElNZXRyaWMsIE1ldHJpYywgTWF0aEV4cHJlc3Npb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBBdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyB9IGZyb20gJy4vcHJvcHMvQXZhaWxhYmlsaXR5TWV0cmljUHJvcHMnO1xuaW1wb3J0IHsgTGF0ZW5jeU1ldHJpY1Byb3BzIH0gZnJvbSAnLi9wcm9wcy9MYXRlbmN5TWV0cmljUHJvcHMnO1xuaW1wb3J0IHsgQXZhaWxhYmlsaXR5TWV0cmljVHlwZSB9IGZyb20gJy4uL3V0aWxpdGllcy9BdmFpbGFiaWxpdHlNZXRyaWNUeXBlJztcbmltcG9ydCB7IExhdGVuY3lNZXRyaWNUeXBlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL0xhdGVuY3lNZXRyaWNUeXBlJztcbmltcG9ydCB7IFpvbmFsQXZhaWxhYmlsaXR5TWV0cmljUHJvcHMgfSBmcm9tICcuL3Byb3BzL1pvbmFsQXZhaWxhYmlsaXR5TWV0cmljUHJvcHMnO1xuaW1wb3J0IHsgWm9uYWxMYXRlbmN5TWV0cmljUHJvcHMgfSBmcm9tICcuL3Byb3BzL1pvbmFsTGF0ZW5jeU1ldHJpY1Byb3BzJztcblxuLyoqXG4gKiBDbGFzcyBmb3IgY3JlYXRpbmcgYXZhaWxhYmlsaXR5IGFuZCBsYXRlbmN5IG1ldHJpY3MgdGhhdCBjYW4gYmUgdXNlZCBpbiBhbGFybXMgYW5kIGdyYXBoc1xuICovXG5leHBvcnQgY2xhc3MgQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3Mge1xuXG4gIC8qKlxuICAgKiBHZW5lcmFsIHB1cnBvc2UgbWV0aG9kIHRvIGNyZWF0ZSBhdmFpbGFiaWxpdHkgbWV0cmljc1xuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHBhcmFtIGRpbWVuc2lvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVBdmFpbGFiaWxpdHlNZXRyaWMoXG4gICAgcHJvcHM6IEF2YWlsYWJpbGl0eU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWMge1xuICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG5cbiAgICBsZXQgc3VjY2Vzc0tleXM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGZhdWx0S2V5czogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmIChcbiAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMuc3VjY2Vzc01ldHJpY05hbWVzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHByb3BzLm1ldHJpY1R5cGUgIT0gQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVFxuICAgICkge1xuICAgICAgcHJvcHMubWV0cmljRGV0YWlscy5zdWNjZXNzTWV0cmljTmFtZXMuZm9yRWFjaCgoc3VjY2Vzc01ldHJpYzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgbGV0IGtleTogc3RyaW5nID0gYCR7cHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCl9XyR7cHJvcHMubWV0cmljVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCl9XyR7c3VjY2Vzc01ldHJpYy50b0xvd2VyQ2FzZSgpfWA7XG5cbiAgICAgICAgICBzdWNjZXNzS2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgICB1c2luZ01ldHJpY3Nba2V5XSA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgICAgbmFtZXNwYWNlOiBwcm9wcy5tZXRyaWNEZXRhaWxzLm1ldHJpY05hbWVzcGFjZSxcbiAgICAgICAgICAgIG1ldHJpY05hbWU6IHN1Y2Nlc3NNZXRyaWMsXG4gICAgICAgICAgICB1bml0OiBwcm9wcy5tZXRyaWNEZXRhaWxzLnVuaXQsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5tZXRyaWNEZXRhaWxzLmFsYXJtU3RhdGlzdGljLFxuICAgICAgICAgICAgZGltZW5zaW9uc01hcDogZGltZW5zaW9ucyxcbiAgICAgICAgICAgIGxhYmVsOiBzdWNjZXNzTWV0cmljLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcm9wcy5tZXRyaWNEZXRhaWxzLmZhdWx0TWV0cmljTmFtZXMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgcHJvcHMubWV0cmljVHlwZSAhPSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlRcbiAgICApIHtcbiAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMuZmF1bHRNZXRyaWNOYW1lcy5mb3JFYWNoKChmYXVsdE1ldHJpYykgPT4ge1xuICAgICAgICBsZXQga2V5OiBzdHJpbmcgPSBgJHtwcm9wcy5tZXRyaWNEZXRhaWxzLm9wZXJhdGlvbk5hbWUudG9Mb3dlckNhc2UoKX1fJHtwcm9wcy5tZXRyaWNUeXBlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKX1fJHtmYXVsdE1ldHJpYy50b0xvd2VyQ2FzZSgpfWA7XG5cbiAgICAgICAgZmF1bHRLZXlzLnB1c2goa2V5KTtcblxuICAgICAgICB1c2luZ01ldHJpY3Nba2V5XSA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgIG5hbWVzcGFjZTogcHJvcHMubWV0cmljRGV0YWlscy5tZXRyaWNOYW1lc3BhY2UsXG4gICAgICAgICAgbWV0cmljTmFtZTogZmF1bHRNZXRyaWMsXG4gICAgICAgICAgdW5pdDogcHJvcHMubWV0cmljRGV0YWlscy51bml0LFxuICAgICAgICAgIHBlcmlvZDogcHJvcHMubWV0cmljRGV0YWlscy5wZXJpb2QsXG4gICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5tZXRyaWNEZXRhaWxzLmFsYXJtU3RhdGlzdGljLFxuICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IGRpbWVuc2lvbnMsXG4gICAgICAgICAgbGFiZWw6IGZhdWx0TWV0cmljLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCBleHByZXNzaW9uOiBzdHJpbmcgPSAnJztcblxuICAgIHN3aXRjaCAocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfUkFURTpcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAoKCR7c3VjY2Vzc0tleXMuam9pbignKycpfSkgLyAoJHtzdWNjZXNzS2V5cy5qb2luKCcrJyl9KyR7ZmF1bHRLZXlzLmpvaW4oJysnKX0pKSAqIDEwMGA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlJFUVVFU1RfQ09VTlQ6XG4gICAgICAgIGV4cHJlc3Npb24gPSBgJHtzdWNjZXNzS2V5cy5qb2luKCcrJyl9KyR7ZmF1bHRLZXlzLmpvaW4oJysnKX1gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9DT1VOVDpcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAoJHtmYXVsdEtleXMuam9pbignKycpfSlgO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmlsaXR5TWV0cmljVHlwZS5GQVVMVF9SQVRFOlxuICAgICAgICBleHByZXNzaW9uID0gYCgoJHtmYXVsdEtleXMuam9pbignKycpfSkgLyAoJHtzdWNjZXNzS2V5cy5qb2luKCcrJyl9KyR7ZmF1bHRLZXlzLmpvaW4oJysnKX0pKSAqIDEwMGA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlQ6XG4gICAgICAgIGV4cHJlc3Npb24gPSBgKCR7c3VjY2Vzc0tleXMuam9pbignKycpfSlgO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgIGV4cHJlc3Npb246IGV4cHJlc3Npb24sXG4gICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICBjb2xvcjogcHJvcHMuY29sb3JcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiAgQ3JlYXRlcyBhdmFpbGFiaWxpdHkgbWV0cmljcyBmb3IgYSBzcGVjaWZpYyBBWlxuICAgKiBAcGFyYW0gcHJvcHMgXG4gICAqIEBwYXJhbSBkaW1lbnNpb25zIFxuICAgKiBAcmV0dXJucyBcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVab25hbEF2YWlsYWJpbGl0eU1ldHJpYyhcbiAgICBwcm9wczogWm9uYWxBdmFpbGFiaWxpdHlNZXRyaWNQcm9wcyxcbiAgICBkaW1lbnNpb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICApOiBJTWV0cmljIHtcbiAgICBsZXQgdXNpbmdNZXRyaWNzOiB7IFtrZXk6IHN0cmluZ106IElNZXRyaWMgfSA9IHt9O1xuXG4gICAgbGV0IHN1Y2Nlc3NLZXlzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBmYXVsdEtleXM6IHN0cmluZ1tdID0gW107XG5cbiAgICBpZiAoXG4gICAgICBwcm9wcy5tZXRyaWNEZXRhaWxzLnN1Y2Nlc3NNZXRyaWNOYW1lcyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBwcm9wcy5tZXRyaWNUeXBlICE9IEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuRkFVTFRfQ09VTlRcbiAgICApIHtcbiAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMuc3VjY2Vzc01ldHJpY05hbWVzLmZvckVhY2goKHN1Y2Nlc3NNZXRyaWM6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGxldCBrZXk6IHN0cmluZyA9IGAke3Byb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSl9XyR7cHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCl9XyR7cHJvcHMubWV0cmljVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCl9XyR7c3VjY2Vzc01ldHJpYy50b0xvd2VyQ2FzZSgpfWA7XG5cbiAgICAgICAgICBzdWNjZXNzS2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgICB1c2luZ01ldHJpY3Nba2V5XSA9IG5ldyBNZXRyaWMoe1xuICAgICAgICAgICAgbmFtZXNwYWNlOiBwcm9wcy5tZXRyaWNEZXRhaWxzLm1ldHJpY05hbWVzcGFjZSxcbiAgICAgICAgICAgIG1ldHJpY05hbWU6IHN1Y2Nlc3NNZXRyaWMsXG4gICAgICAgICAgICB1bml0OiBwcm9wcy5tZXRyaWNEZXRhaWxzLnVuaXQsXG4gICAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBwcm9wcy5tZXRyaWNEZXRhaWxzLmFsYXJtU3RhdGlzdGljLFxuICAgICAgICAgICAgZGltZW5zaW9uc01hcDogZGltZW5zaW9ucyxcbiAgICAgICAgICAgIGxhYmVsOiBzdWNjZXNzTWV0cmljLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBwcm9wcy5tZXRyaWNEZXRhaWxzLmZhdWx0TWV0cmljTmFtZXMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgcHJvcHMubWV0cmljVHlwZSAhPSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLlNVQ0NFU1NfQ09VTlRcbiAgICApIHtcbiAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMuZmF1bHRNZXRyaWNOYW1lcy5mb3JFYWNoKChmYXVsdE1ldHJpYykgPT4ge1xuICAgICAgICBsZXQga2V5OiBzdHJpbmcgPSBgJHtwcm9wcy5hdmFpbGFiaWxpdHlab25lLnN1YnN0cmluZyhwcm9wcy5hdmFpbGFiaWxpdHlab25lLmxlbmd0aCAtIDEpfV8ke3Byb3BzLm1ldHJpY0RldGFpbHMub3BlcmF0aW9uTmFtZS50b0xvd2VyQ2FzZSgpfV8ke3Byb3BzLm1ldHJpY1R5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpfV8ke2ZhdWx0TWV0cmljLnRvTG93ZXJDYXNlKCl9YDtcblxuICAgICAgICBmYXVsdEtleXMucHVzaChrZXkpO1xuXG4gICAgICAgIHVzaW5nTWV0cmljc1trZXldID0gbmV3IE1ldHJpYyh7XG4gICAgICAgICAgbmFtZXNwYWNlOiBwcm9wcy5tZXRyaWNEZXRhaWxzLm1ldHJpY05hbWVzcGFjZSxcbiAgICAgICAgICBtZXRyaWNOYW1lOiBmYXVsdE1ldHJpYyxcbiAgICAgICAgICB1bml0OiBwcm9wcy5tZXRyaWNEZXRhaWxzLnVuaXQsXG4gICAgICAgICAgcGVyaW9kOiBwcm9wcy5tZXRyaWNEZXRhaWxzLnBlcmlvZCxcbiAgICAgICAgICBzdGF0aXN0aWM6IHByb3BzLm1ldHJpY0RldGFpbHMuYWxhcm1TdGF0aXN0aWMsXG4gICAgICAgICAgZGltZW5zaW9uc01hcDogZGltZW5zaW9ucyxcbiAgICAgICAgICBsYWJlbDogZmF1bHRNZXRyaWMsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IGV4cHJlc3Npb246IHN0cmluZyA9ICcnO1xuXG4gICAgc3dpdGNoIChwcm9wcy5tZXRyaWNUeXBlKSB7XG4gICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuU1VDQ0VTU19SQVRFOlxuICAgICAgICBleHByZXNzaW9uID0gYCgoJHtzdWNjZXNzS2V5cy5qb2luKCcrJyl9KSAvICgke3N1Y2Nlc3NLZXlzLmpvaW4oJysnKX0rJHtmYXVsdEtleXMuam9pbignKycpfSkpICogMTAwYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuUkVRVUVTVF9DT1VOVDpcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAke3N1Y2Nlc3NLZXlzLmpvaW4oJysnKX0rJHtmYXVsdEtleXMuam9pbignKycpfWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX0NPVU5UOlxuICAgICAgICBleHByZXNzaW9uID0gYCgke2ZhdWx0S2V5cy5qb2luKCcrJyl9KWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFiaWxpdHlNZXRyaWNUeXBlLkZBVUxUX1JBVEU6XG4gICAgICAgIGV4cHJlc3Npb24gPSBgKCgke2ZhdWx0S2V5cy5qb2luKCcrJyl9KSAvICgke3N1Y2Nlc3NLZXlzLmpvaW4oJysnKX0rJHtmYXVsdEtleXMuam9pbignKycpfSkpICogMTAwYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJpbGl0eU1ldHJpY1R5cGUuU1VDQ0VTU19DT1VOVDpcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAoJHtzdWNjZXNzS2V5cy5qb2luKCcrJyl9KWA7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTWF0aEV4cHJlc3Npb24oe1xuICAgICAgZXhwcmVzc2lvbjogZXhwcmVzc2lvbixcbiAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgIHBlcmlvZDogcHJvcHMubWV0cmljRGV0YWlscy5wZXJpb2QsXG4gICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgIGNvbG9yOiBwcm9wcy5jb2xvclxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYWwgcHVycG9zZSBtZXRob2QgdG8gY3JlYXRlIGxhdGVuY3kgbWV0cmljcywgdGhlIHJlYXNvbiB0aGlzIGNyZWF0ZXMgYW4gYXJyYXkgb2YgbWV0cmljcyB3aGlsZSB0aGVcbiAgICogZXF1aXZhbGVudCBhdmFpbGFiaWxpdHkgbWV0cmljIG1ldGhvZCBkb2Vzbid0IGlzIGJlY2F1c2UgaW4gYXZhaWxhYmlsaXR5LCB3ZSBjYW4ganVzdCBzdW0gdGhlIGNvdW50IG9mIGRpZmZlcmVudFxuICAgKiBtZXRyaWMgbmFtZXMgd2hpbGUgZm9yIGxhdGVuY3kgd2UgY2FuJ3Qgc3VtIHRoZSBjb3VudCBiZWNhdXNlIHRoYXQncyBub3Qgd2hhdCdzIGJlaW5nIG1lYXN1cmVkLiBJdCBhbGxvd3MgdGhlXG4gICAqIGNhbGxlciB0byBkZWNpZGUgaWYgdGhleSBvbmx5IHdhbnQgdG8gdGFrZSB0aGUgZmlyc3QgbmFtZSwgb3IgYXZlcmFnZSBhbGwgb2YgdGhlIG5hbWVzXG4gICAqIChsaWtlIFN1Y2Nlc3NMYXRlbmN5IGFuZCBCaWdJdGVtU3VjY2Vzc0xhdGVuY3kpLlxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHNcbiAgICogQHBhcmFtIGRpbWVuc2lvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVMYXRlbmN5TWV0cmljcyhcbiAgICBwcm9wczogTGF0ZW5jeU1ldHJpY1Byb3BzLFxuICAgIGRpbWVuc2lvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sXG4gICk6IElNZXRyaWNbXSB7XG4gICAgbGV0IG5hbWVzOiBzdHJpbmdbXTtcblxuICAgIHN3aXRjaCAocHJvcHMubWV0cmljVHlwZSkge1xuICAgICAgZGVmYXVsdDpcbiAgICAgIGNhc2UgTGF0ZW5jeU1ldHJpY1R5cGUuU1VDQ0VTU19MQVRFTkNZOlxuICAgICAgICBuYW1lcyA9IHByb3BzLm1ldHJpY0RldGFpbHMuc3VjY2Vzc01ldHJpY05hbWVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTGF0ZW5jeU1ldHJpY1R5cGUuRkFVTFRfTEFURU5DWTpcbiAgICAgICAgbmFtZXMgPSBwcm9wcy5tZXRyaWNEZXRhaWxzLmZhdWx0TWV0cmljTmFtZXM7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBuYW1lcy5tYXAoXG4gICAgICAoeCkgPT5cbiAgICAgICAgbmV3IE1ldHJpYyh7XG4gICAgICAgICAgbWV0cmljTmFtZTogeCxcbiAgICAgICAgICBuYW1lc3BhY2U6IHByb3BzLm1ldHJpY0RldGFpbHMubWV0cmljTmFtZXNwYWNlLFxuICAgICAgICAgIHVuaXQ6IHByb3BzLm1ldHJpY0RldGFpbHMudW5pdCxcbiAgICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICAgIHN0YXRpc3RpYzogcHJvcHMuc3RhdGlzdGljLFxuICAgICAgICAgIGRpbWVuc2lvbnNNYXA6IGRpbWVuc2lvbnMsXG4gICAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBsYXRlbmN5IG1ldHJpYyB3aXRoIHRoZSBwcm92aWRlZCBuYW1lXG4gICAqIEBwYXJhbSBwcm9wcyBcbiAgICogQHBhcmFtIGRpbWVuc2lvbnMgXG4gICAqIEByZXR1cm5zIFxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZUxhdGVuY3lNZXRyaWMoXG4gICAgcHJvcHM6IExhdGVuY3lNZXRyaWNQcm9wcyxcbiAgICBkaW1lbnNpb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9XG4gICk6IElNZXRyaWMge1xuICAgIGlmICghKHByb3BzLm1ldHJpY05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJZb3UgbXVzdCBwcm92aWRlIGEgbWV0cmljIG5hbWUuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIG1ldHJpY05hbWU6IHByb3BzLm1ldHJpY05hbWUhLFxuICAgICAgbmFtZXNwYWNlOiBwcm9wcy5tZXRyaWNEZXRhaWxzLm1ldHJpY05hbWVzcGFjZSxcbiAgICAgIHVuaXQ6IHByb3BzLm1ldHJpY0RldGFpbHMudW5pdCxcbiAgICAgIHBlcmlvZDogcHJvcHMubWV0cmljRGV0YWlscy5wZXJpb2QsXG4gICAgICBzdGF0aXN0aWM6IHByb3BzLnN0YXRpc3RpYyxcbiAgICAgIGRpbWVuc2lvbnNNYXA6IGRpbWVuc2lvbnMsXG4gICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICBjb2xvcjogcHJvcHMuY29sb3JcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYWtlcyBhbGwgb2YgdGhlIHN1Y2Nlc3Mgb3IgZmFpbHVyZSBsYXRlbmN5IG1ldHJpYyBuYW1lcyBhbmQgY3JlYXRlcyBhbiBhdmVyYWdlIG9mIHRob3NlXG4gICAqIG5hbWVzLCBpZiB0aGVyZSdzIG9ubHkgMSBuYW1lLCBpdCBqdXN0IHJldHVybnMgdGhhdCBtZXRyaWNcbiAgICogQHBhcmFtIHByb3BzXG4gICAqIEBwYXJhbSBkaW1lbnNpb25zXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlQXZlcmFnZUxhdGVuY3lNZXRyaWMoXG4gICAgcHJvcHM6IExhdGVuY3lNZXRyaWNQcm9wcyxcbiAgICBkaW1lbnNpb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICApOiBJTWV0cmljIHtcbiAgICBsZXQgbGF0ZW5jeU1ldHJpY3M6IElNZXRyaWNbXSA9XG4gICAgICBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVMYXRlbmN5TWV0cmljcyhwcm9wcywgZGltZW5zaW9ucyk7XG5cbiAgICBpZiAobGF0ZW5jeU1ldHJpY3MubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiBsYXRlbmN5TWV0cmljc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgICAgbGF0ZW5jeU1ldHJpY3MuZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBrZXlQcmVmaXg6IHN0cmluZyA9XG4gICAgICAgICAgKHByb3BzLmtleVByZWZpeCA9PT0gdW5kZWZpbmVkIHx8IHByb3BzLmtleVByZWZpeCA9PSAnJ1xuICAgICAgICAgICAgPyAnJ1xuICAgICAgICAgICAgOiBwcm9wcy5rZXlQcmVmaXgudG9Mb3dlckNhc2UoKSArICdfJykgK1xuICAgICAgICAgIHByb3BzLm1ldHJpY0RldGFpbHMub3BlcmF0aW9uTmFtZS50b0xvd2VyQ2FzZSgpICtcbiAgICAgICAgICAnXycgK1xuICAgICAgICAgIHByb3BzLm1ldHJpY1R5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgIHVzaW5nTWV0cmljc1trZXlQcmVmaXggKyBpbmRleF0gPSBtZXRyaWM7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgIGV4cHJlc3Npb246IGAoJHtPYmplY3Qua2V5cyh1c2luZ01ldHJpY3MpLmpvaW4oJysnKX0pLyR7T2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5sZW5ndGh9YCxcbiAgICAgICAgbGFiZWw6IHByb3BzLmxhYmVsLFxuICAgICAgICBwZXJpb2Q6IHByb3BzLm1ldHJpY0RldGFpbHMucGVyaW9kLFxuICAgICAgICB1c2luZ01ldHJpY3M6IHVzaW5nTWV0cmljcyxcbiAgICAgICAgY29sb3I6IHByb3BzLmNvbG9yXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGNvdW50IG9mIGhpZ2ggbGF0ZW5jeSBtZXRyaWNzIGZvciBlaXRoZXIgU3VjY2Vzc0xhdGVuY3kgb3IgRmF1bHRMYXRlbmN5LCB3aWxsIHRvdGFsXG4gICAqIHRoZSBjb3VudCBvZiByZXF1ZXN0cyB0aGF0IGV4Y2VlZCBhIHRocmVzaG9sZCB5b3UgZGVmaW5lIGluIHlvdXIgc3RhdGlzdGljLCBsaWtlIFRDKDIwMDopIGFjcm9zc1xuICAgKiBhbGwgbWV0cmljIG5hbWVzIHRoYXQgYXJlIHBhcnQgb2YgZWl0aGVyIFN1Y2Nlc3Mgb3IgRmF1bHQgbGF0ZW5jeS5cbiAgICogQHBhcmFtIHByb3BzXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTGF0ZW5jeUNvdW50TWV0cmljKFxuICAgIHByb3BzOiBMYXRlbmN5TWV0cmljUHJvcHMsXG4gICAgZGltZW5zaW9uczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSxcbiAgKTogSU1ldHJpYyB7XG4gICAgbGV0IGxhdGVuY3lNZXRyaWNzOiBJTWV0cmljW10gPVxuICAgICAgQXZhaWxhYmlsaXR5QW5kTGF0ZW5jeU1ldHJpY3MuY3JlYXRlTGF0ZW5jeU1ldHJpY3MocHJvcHMsIGRpbWVuc2lvbnMpO1xuXG4gICAgaWYgKGxhdGVuY3lNZXRyaWNzLmxlbmd0aCA9PSAxKSB7XG4gICAgICByZXR1cm4gbGF0ZW5jeU1ldHJpY3NbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCB1c2luZ01ldHJpY3M6IHsgW2tleTogc3RyaW5nXTogSU1ldHJpYyB9ID0ge307XG5cbiAgICAgIGxhdGVuY3lNZXRyaWNzLmZvckVhY2goKG1ldHJpYzogSU1ldHJpYywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBsZXQga2V5OiBzdHJpbmcgPSBgJHtwcm9wcy5tZXRyaWNEZXRhaWxzLm9wZXJhdGlvbk5hbWUudG9Mb3dlckNhc2UoKX1fJHtwcm9wcy5tZXRyaWNUeXBlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKX1fJHtpbmRleH1gO1xuICAgICAgICB1c2luZ01ldHJpY3Nba2V5XSA9IG1ldHJpYztcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IE1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgZXhwcmVzc2lvbjogT2JqZWN0LmtleXModXNpbmdNZXRyaWNzKS5qb2luKCcrJyksXG4gICAgICAgIGxhYmVsOiBwcm9wcy5sYWJlbCxcbiAgICAgICAgcGVyaW9kOiBwcm9wcy5tZXRyaWNEZXRhaWxzLnBlcmlvZCxcbiAgICAgICAgdXNpbmdNZXRyaWNzOiB1c2luZ01ldHJpY3MsXG4gICAgICAgIGNvbG9yOiBwcm9wcy5jb2xvclxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNyZWF0ZVpvbmFsTGF0ZW5jeUNvdW50TWV0cmljKFxuICAgIHByb3BzOiBab25hbExhdGVuY3lNZXRyaWNQcm9wcyxcbiAgICBkaW1lbnNpb25zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9LFxuICApOiBJTWV0cmljIHtcbiAgICBsZXQgbGF0ZW5jeU1ldHJpY3M6IElNZXRyaWNbXSA9XG4gICAgICBBdmFpbGFiaWxpdHlBbmRMYXRlbmN5TWV0cmljcy5jcmVhdGVMYXRlbmN5TWV0cmljcyhwcm9wcywgZGltZW5zaW9ucyk7XG5cbiAgICBpZiAobGF0ZW5jeU1ldHJpY3MubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiBsYXRlbmN5TWV0cmljc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHVzaW5nTWV0cmljczogeyBba2V5OiBzdHJpbmddOiBJTWV0cmljIH0gPSB7fTtcblxuICAgICAgbGF0ZW5jeU1ldHJpY3MuZm9yRWFjaCgobWV0cmljOiBJTWV0cmljLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGxldCBrZXk6IHN0cmluZyA9IGAke3Byb3BzLmF2YWlsYWJpbGl0eVpvbmUuc3Vic3RyaW5nKHByb3BzLmF2YWlsYWJpbGl0eVpvbmUubGVuZ3RoIC0gMSl9XyR7cHJvcHMubWV0cmljRGV0YWlscy5vcGVyYXRpb25OYW1lLnRvTG93ZXJDYXNlKCl9XyR7cHJvcHMubWV0cmljVHlwZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCl9XyR7aW5kZXh9YDtcbiAgICAgICAgdXNpbmdNZXRyaWNzW2tleV0gPSBtZXRyaWM7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG5ldyBNYXRoRXhwcmVzc2lvbih7XG4gICAgICAgIGV4cHJlc3Npb246IE9iamVjdC5rZXlzKHVzaW5nTWV0cmljcykuam9pbignKycpLFxuICAgICAgICBsYWJlbDogcHJvcHMubGFiZWwsXG4gICAgICAgIHBlcmlvZDogcHJvcHMubWV0cmljRGV0YWlscy5wZXJpb2QsXG4gICAgICAgIHVzaW5nTWV0cmljczogdXNpbmdNZXRyaWNzLFxuICAgICAgICBjb2xvcjogcHJvcHMuY29sb3JcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,113 @@
1
+ import { CfnNatGateway } from "aws-cdk-lib/aws-ec2";
2
+ import { IAlarm, IMetric, IWidget } from "aws-cdk-lib/aws-cloudwatch";
3
+ import { Duration } from "aws-cdk-lib";
4
+ import { IConstruct } from "constructs";
5
+ import { IAvailabilityZoneMapper } from "../azmapper/IAvailabilityZoneMapper";
6
+ import { PacketLossOutlierAlgorithm } from "../outlier-detection/PacketLossOutlierAlgorithm";
7
+ /**
8
+ * Provides functions for getting CloudWatch metrics and alarms for NAT Gateways.
9
+ */
10
+ export declare class NatGatewayMetrics {
11
+ /**
12
+ * Gets the count of packet drops for all NAT Gateways that belong to the provided AZ
13
+ * @param natgws
14
+ * @param availabilityZoneId
15
+ * @param period
16
+ * @returns
17
+ */
18
+ static getDroppedPacketCountMetricForAZ(natgws: CfnNatGateway[], availabilityZoneId: string, period: Duration, prefix?: string, color?: string): IMetric;
19
+ /**
20
+ * Get the packet drop rate for all NAT Gateways that belong to the provided AZ
21
+ * @param natgws
22
+ * @param availabilityZoneId
23
+ * @param period
24
+ * @returns Percent of packet drops like 52%
25
+ */
26
+ static getDroppedPacketRateMetricForAZ(natgws: CfnNatGateway[], availabilityZoneId: string, period: Duration, prefix?: string, color?: string): IMetric;
27
+ /**
28
+ * Get the packet count for all NAT Gateways that belong to the provided AZ
29
+ * @param natgws
30
+ * @param availabilityZoneId
31
+ * @param period
32
+ * @returns
33
+ */
34
+ static getTotalPacketCountMetricForAZ(natgws: CfnNatGateway[], availabilityZoneId: string, period: Duration, prefix?: string, color?: string): IMetric;
35
+ /**
36
+ * Returns an alarm indicating if the quantity of packet drops in a single AZ across all NAT Gateways in that
37
+ * AZ exceeds a threshold compared to all packet loss across all AZs.
38
+ *
39
+ * For example:
40
+ *
41
+ * A = 150 packets
42
+ * B = 175 packets
43
+ * C = 160 packets
44
+ *
45
+ * And the selected AZ is "A", then the calculation is 150 / (150 + 175 + 160).
46
+ *
47
+ * @param scope
48
+ * @param natgws
49
+ * @param availabilityZoneId
50
+ * @param availabilityZone
51
+ * @param threshold
52
+ * @param period
53
+ * @param evaluationPeriods
54
+ * @param datapointsToAlarm
55
+ * @returns
56
+ */
57
+ static isAZAnOutlierForPacketLossNATGW(scope: IConstruct, natgws: {
58
+ [key: string]: CfnNatGateway[];
59
+ }, algorithm: PacketLossOutlierAlgorithm, availabilityZone: string, azMapper: IAvailabilityZoneMapper, threshold: number, period: Duration, evaluationPeriods: number, datapointsToAlarm: number): IAlarm;
60
+ /**
61
+ * Creates an alarm to determine is the packet loss rate in a single AZ across all NAT Gateways provided
62
+ * for that AZ exceed the provided threshold.
63
+ * @param scope
64
+ * @param natgws
65
+ * @param availabilityZoneId
66
+ * @param availabilityZone
67
+ * @param threshold
68
+ * @param period
69
+ * @param evaluationPeriods
70
+ * @param datapointsToAlarm
71
+ * @returns
72
+ */
73
+ static isThereAnAZPacketLossImpactNATGW(scope: IConstruct, natgws: CfnNatGateway[], availabilityZoneId: string, availabilityZone: string, threshold: number, period: Duration, evaluationPeriods: number, datapointsToAlarm: number): IAlarm;
74
+ /**
75
+ * Gets the count of all packets from all NAT Gateways in each provided Availability Zone.
76
+ * @param natgws
77
+ * @param azMapper
78
+ * @param period
79
+ * @returns
80
+ */
81
+ static getTotalPacketCountForEveryAZ(natgws: {
82
+ [key: string]: CfnNatGateway[];
83
+ }, azMapper: IAvailabilityZoneMapper, period: Duration): {
84
+ [key: string]: IMetric;
85
+ };
86
+ /**
87
+ * Gets the count of packet drops from all NAT Gateways in each provided Availability Zone.
88
+ * @param natgws
89
+ * @param azMapper
90
+ * @param period
91
+ * @returns
92
+ */
93
+ static getTotalPacketDropsForEveryAZ(natgws: {
94
+ [key: string]: CfnNatGateway[];
95
+ }, azMapper: IAvailabilityZoneMapper, period: Duration): {
96
+ [key: string]: IMetric;
97
+ };
98
+ /**
99
+ * Gets the packet drop rate from all NAT Gateways in each provided Availability Zone.
100
+ * @param natgws
101
+ * @param azMapper
102
+ * @param period
103
+ * @returns
104
+ */
105
+ static getTotalPacketDropRateForEveryAZ(natgws: {
106
+ [key: string]: CfnNatGateway[];
107
+ }, azMapper: IAvailabilityZoneMapper, period: Duration): {
108
+ [key: string]: IMetric;
109
+ };
110
+ static generateNatGatewayWidgets(natgws: {
111
+ [key: string]: CfnNatGateway[];
112
+ }, azMapper: IAvailabilityZoneMapper, period: Duration, packetDropRateThreshold: number): IWidget[];
113
+ }