pepr 0.1.8 → 0.1.9

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.
package/src/lib/types.ts CHANGED
@@ -80,16 +80,18 @@ export type ModuleSigning = {
80
80
  authorizedKeys?: string[];
81
81
  };
82
82
 
83
- export type ModulePackageCfg = {
83
+ /** Global configuration for the Pepr runtime. */
84
+ export type ModuleConfig = {
85
+ /** The user-defined name for the module */
86
+ name: string;
87
+ /** The version of Pepr that the module was originally generated with */
88
+ version: string;
84
89
  /** A unique identifier for this Pepr module. This is automatically generated by Pepr. */
85
90
  uuid: string;
86
91
  /** A description of the Pepr module and what it does. */
87
- description: string;
92
+ description?: string;
88
93
  /** Reject K8s resource AdmissionRequests on error. */
89
- onError: ErrorBehavior;
90
- };
91
-
92
- export type ModuleAdditionalCfg = {
94
+ onError: ErrorBehavior | string;
93
95
  /** Configure global exclusions that will never be processed by Pepr. */
94
96
  alwaysIgnore: WebhookIgnore;
95
97
  /**
@@ -101,9 +103,6 @@ export type ModuleAdditionalCfg = {
101
103
  signing?: ModuleSigning;
102
104
  };
103
105
 
104
- /** Global configuration for the Pepr runtime. */
105
- export type ModuleConfig = ModulePackageCfg & ModuleAdditionalCfg;
106
-
107
106
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
107
  export type GenericClass = abstract new () => any;
109
108
 
package/tsconfig.json CHANGED
@@ -7,5 +7,6 @@
7
7
  "resolveJsonModule": true,
8
8
  "strict": false,
9
9
  "target": "ES2020"
10
- }
10
+ },
11
+ "include": ["src/**/*.ts"]
11
12
  }
@@ -1,393 +0,0 @@
1
- 'use strict';
2
-
3
- require('@kubernetes/client-node/dist');
4
- var R = require('ramda');
5
- var fastJsonPatch = require('fast-json-patch');
6
-
7
- function _interopNamespaceDefault(e) {
8
- var n = Object.create(null);
9
- if (e) {
10
- Object.keys(e).forEach(function (k) {
11
- if (k !== 'default') {
12
- var d = Object.getOwnPropertyDescriptor(e, k);
13
- Object.defineProperty(n, k, d.get ? d : {
14
- enumerable: true,
15
- get: function () { return e[k]; }
16
- });
17
- }
18
- });
19
- }
20
- n.default = e;
21
- return Object.freeze(n);
22
- }
23
-
24
- var R__namespace = /*#__PURE__*/_interopNamespaceDefault(R);
25
-
26
- var LogLevel;
27
- (function (LogLevel) {
28
- LogLevel[LogLevel["debug"] = 0] = "debug";
29
- LogLevel[LogLevel["info"] = 1] = "info";
30
- LogLevel[LogLevel["warn"] = 2] = "warn";
31
- LogLevel[LogLevel["error"] = 3] = "error";
32
- })(LogLevel || (LogLevel = {}));
33
- var ConsoleColors;
34
- (function (ConsoleColors) {
35
- ConsoleColors["Reset"] = "\u001B[0m";
36
- ConsoleColors["Bright"] = "\u001B[1m";
37
- ConsoleColors["Dim"] = "\u001B[2m";
38
- ConsoleColors["Underscore"] = "\u001B[4m";
39
- ConsoleColors["Blink"] = "\u001B[5m";
40
- ConsoleColors["Reverse"] = "\u001B[7m";
41
- ConsoleColors["Hidden"] = "\u001B[8m";
42
- ConsoleColors["FgBlack"] = "\u001B[30m";
43
- ConsoleColors["FgRed"] = "\u001B[31m";
44
- ConsoleColors["FgGreen"] = "\u001B[32m";
45
- ConsoleColors["FgYellow"] = "\u001B[33m";
46
- ConsoleColors["FgBlue"] = "\u001B[34m";
47
- ConsoleColors["FgMagenta"] = "\u001B[35m";
48
- ConsoleColors["FgCyan"] = "\u001B[36m";
49
- ConsoleColors["FgWhite"] = "\u001B[37m";
50
- ConsoleColors["BgBlack"] = "\u001B[40m";
51
- ConsoleColors["BgRed"] = "\u001B[41m";
52
- ConsoleColors["BgGreen"] = "\u001B[42m";
53
- ConsoleColors["BgYellow"] = "\u001B[43m";
54
- ConsoleColors["BgBlue"] = "\u001B[44m";
55
- ConsoleColors["BgMagenta"] = "\u001B[45m";
56
- ConsoleColors["BgCyan"] = "\u001B[46m";
57
- ConsoleColors["BgWhite"] = "\u001B[47m";
58
- })(ConsoleColors || (ConsoleColors = {}));
59
- class Logger {
60
- constructor(logLevel) {
61
- this._logLevel = logLevel;
62
- }
63
- SetLogLevel(logLevel) {
64
- this._logLevel = LogLevel[logLevel];
65
- this.debug(`Log level set to ${logLevel}`);
66
- }
67
- debug(message, prefix) {
68
- this.log(LogLevel.debug, message, prefix);
69
- }
70
- info(message, prefix) {
71
- this.log(LogLevel.info, message, prefix);
72
- }
73
- warn(message, prefix) {
74
- this.log(LogLevel.warn, message, prefix);
75
- }
76
- error(message, prefix) {
77
- this.log(LogLevel.error, message, prefix);
78
- }
79
- log(logLevel, message, callerPrefix = "") {
80
- const color = {
81
- [LogLevel.debug]: ConsoleColors.FgBlack,
82
- [LogLevel.info]: ConsoleColors.FgCyan,
83
- [LogLevel.warn]: ConsoleColors.FgYellow,
84
- [LogLevel.error]: ConsoleColors.FgRed,
85
- };
86
- if (logLevel >= this._logLevel) {
87
- let prefix = "[" + LogLevel[logLevel] + "]\t" + callerPrefix;
88
- prefix = this.colorize(prefix, color[logLevel]);
89
- if (typeof message !== "string") {
90
- console.log(prefix);
91
- console.debug("%o", message);
92
- }
93
- else {
94
- console.log(prefix + "\t" + message);
95
- }
96
- }
97
- }
98
- colorize(text, color) {
99
- return color + text + ConsoleColors.Reset;
100
- }
101
- }
102
- var logger = new Logger(LogLevel.info);
103
-
104
- var Operation;
105
- (function (Operation) {
106
- Operation["CREATE"] = "CREATE";
107
- Operation["UPDATE"] = "UPDATE";
108
- Operation["DELETE"] = "DELETE";
109
- Operation["CONNECT"] = "CONNECT";
110
- })(Operation || (Operation = {}));
111
-
112
- var ErrorBehavior;
113
- (function (ErrorBehavior) {
114
- ErrorBehavior["ignore"] = "ignore";
115
- ErrorBehavior["audit"] = "audit";
116
- ErrorBehavior["reject"] = "reject";
117
- })(ErrorBehavior || (ErrorBehavior = {}));
118
- var HookPhase;
119
- (function (HookPhase) {
120
- HookPhase["mutate"] = "mutate";
121
- HookPhase["valdiate"] = "validate";
122
- })(HookPhase || (HookPhase = {}));
123
- var Event;
124
- (function (Event) {
125
- Event["Create"] = "create";
126
- Event["Update"] = "update";
127
- Event["Delete"] = "delete";
128
- Event["CreateOrUpdate"] = "createOrUpdate";
129
- })(Event || (Event = {}));
130
-
131
- class RequestWrapper {
132
- get PermitSideEffects() {
133
- return !this._input.dryRun;
134
- }
135
- get IsDryRun() {
136
- return this._input.dryRun;
137
- }
138
- get OldResource() {
139
- return this._input.oldObject;
140
- }
141
- get Request() {
142
- return this._input;
143
- }
144
- constructor(input) {
145
- this.Raw = R__namespace.clone(input.object);
146
- this._input = input;
147
- }
148
- Merge(obj) {
149
- this.Raw = R__namespace.mergeDeepRight(this.Raw, obj);
150
- }
151
- SetLabel(key, value) {
152
- const ref = this.Raw;
153
- ref.metadata = ref.metadata ?? {};
154
- ref.metadata.labels = ref.metadata.labels ?? {};
155
- ref.metadata.labels[key] = value;
156
- return this;
157
- }
158
- SetAnnotation(key, value) {
159
- const ref = this.Raw;
160
- ref.metadata = ref.metadata ?? {};
161
- ref.metadata.annotations = ref.metadata.annotations ?? {};
162
- ref.metadata.annotations[key] = value;
163
- return this;
164
- }
165
- RemoveLabel(key) {
166
- if (this.Raw.metadata?.labels?.[key]) {
167
- delete this.Raw.metadata.labels[key];
168
- }
169
- return this;
170
- }
171
- RemoveAnnotation(key) {
172
- if (this.Raw.metadata?.annotations?.[key]) {
173
- delete this.Raw.metadata.annotations[key];
174
- }
175
- return this;
176
- }
177
- HasLabel(key) {
178
- return this.Raw?.metadata?.labels?.[key] !== undefined;
179
- }
180
- HasAnnotation(key) {
181
- return this.Raw?.metadata?.annotations?.[key] !== undefined;
182
- }
183
- }
184
-
185
- function shouldSkipRequest(binding, req) {
186
- const { group, kind, version } = binding.kind;
187
- const { namespaces, labels, annotations } = binding.filters;
188
- const { metadata } = req.object;
189
- if (kind !== req.kind.kind) {
190
- logger.debug(`${req.kind.kind} does not match ${kind}`);
191
- return true;
192
- }
193
- if (group && group !== req.kind.group) {
194
- logger.debug(`${req.kind.group} does not match ${group}`);
195
- return true;
196
- }
197
- if (version && version !== req.kind.version) {
198
- logger.debug(`${req.kind.version} does not match ${version}`);
199
- return true;
200
- }
201
- if (namespaces.length && !namespaces.includes(req.namespace || "")) {
202
- logger.debug(`${req.namespace} is not in ${namespaces}`);
203
- return true;
204
- }
205
- for (const [key, value] of Object.entries(labels)) {
206
- if (metadata?.labels?.[key] !== value) {
207
- logger.debug(`${metadata?.labels?.[key]} does not match ${value}`);
208
- return true;
209
- }
210
- }
211
- for (const [key, value] of Object.entries(annotations)) {
212
- if (metadata?.annotations?.[key] !== value) {
213
- logger.debug(`${metadata?.annotations?.[key]} does not match ${value}`);
214
- return true;
215
- }
216
- }
217
- return false;
218
- }
219
-
220
- function processor(config, capabilities, req) {
221
- const wrapped = new RequestWrapper(req);
222
- const response = {
223
- uid: req.uid,
224
- patchType: "JSONPatch",
225
- warnings: [],
226
- allowed: false,
227
- };
228
- logger.info(`Processing '${req.uid}' for '${req.kind.kind}' '${req.name}'`);
229
- for (const { name, bindings } of capabilities) {
230
- const prefix = `${req.uid} ${req.name}: ${name}`;
231
- logger.info(`Processing capability ${name}`, prefix);
232
- for (const action of bindings) {
233
- if (shouldSkipRequest(action, req)) {
234
- continue;
235
- }
236
- logger.info(`Processing matched action ${action.kind.kind}`, prefix);
237
- const { metadata } = wrapped.Raw;
238
- const identifier = `pepr.dev/${config.uuid}/${name}`;
239
- metadata.annotations = metadata.annotations || {};
240
- metadata.annotations[identifier] = "started";
241
- try {
242
- action.callback(wrapped);
243
- metadata.annotations[identifier] = "succeeded";
244
- }
245
- catch (e) {
246
- response.warnings.push(`Action failed: ${e}`);
247
- if (config.onError) {
248
- logger.error(`Action failed: ${e}`, prefix);
249
- response.result = "Pepr module configured to reject on error";
250
- return response;
251
- }
252
- else {
253
- logger.warn(`Action failed: ${e}`, prefix);
254
- metadata.annotations[identifier] = "warning";
255
- }
256
- }
257
- }
258
- }
259
- response.allowed = true;
260
- const patches = fastJsonPatch.compare(req.object, wrapped.Raw);
261
- if (patches.length > 0) {
262
- response.patch = JSON.stringify(patches);
263
- }
264
- if (response.warnings.length < 1) {
265
- delete response.warnings;
266
- }
267
- logger.debug(patches);
268
- return response;
269
- }
270
-
271
- class PeprModule {
272
- get kinds() {
273
- return this._kinds;
274
- }
275
- get UUID() {
276
- return this._config.uuid;
277
- }
278
- constructor({ description, pepr }, additionalCfg) {
279
- this._state = [];
280
- this._kinds = [];
281
- this.Register = (capability) => {
282
- logger.info(`Registering capability ${capability.name}`);
283
- this._kinds = capability.bindings.map(({ kind }) => kind);
284
- this._state.push(capability);
285
- };
286
- this.ProcessRequest = (req) => {
287
- return processor(this._config, this._state, req);
288
- };
289
- this._config = {
290
- alwaysIgnore: {
291
- namespaces: ["kube-system", "pepr-system"],
292
- labels: [{ "pepr.dev": "ignore" }],
293
- },
294
- ...pepr,
295
- ...additionalCfg,
296
- description,
297
- };
298
- }
299
- }
300
-
301
- var name = "pepr";
302
- var version = "0.1.4";
303
- var description = "Kubernetes application engine";
304
- var author = "Defense Unicorns";
305
- var homepage = "https://github.com/defenseunicorns/pepr";
306
- var license = "Apache-2.0";
307
- var bin = "dist/pepr-cli.js";
308
- var repository = "defenseunicorns/pepr";
309
- var engines = {
310
- node: ">=18.0.0"
311
- };
312
- var pepr = {
313
- name: "Development Module",
314
- uuid: "20e17cf6-a2e4-46b2-b626-75d88d96c88b",
315
- description: "Development module for pepr",
316
- version: "dev",
317
- onError: "ignore"
318
- };
319
- var scripts = {
320
- webhook: "node dist/default.js",
321
- build: "rollup -c",
322
- start: "rollup -c -w --watch.onEnd 'sleep 1 && node dist/pepr-test.js'",
323
- test: "ava",
324
- lint: "npx eslint src",
325
- "lint:fix": "npm run lint -- --fix",
326
- prettier: "npx prettier src --check",
327
- "prettier:fix": "npm run prettier -- --write",
328
- prepublishOnly: "npm run lint:fix && npm run prettier:fix && npm run test && npm run build"
329
- };
330
- var dependencies = {
331
- "@kubernetes/client-node": "^0.18.1",
332
- "@rollup/plugin-json": "^6.0.0",
333
- "@rollup/plugin-node-resolve": "^15.0.1",
334
- "@rollup/plugin-typescript": "^11.0.0",
335
- "@types/ramda": "^0.28.23",
336
- chokidar: "^3.5.3",
337
- commander: "^10.0.0",
338
- express: "^4.18.2",
339
- "fast-json-patch": "^3.1.1",
340
- prompts: "^2.4.2",
341
- ramda: "^0.28.0",
342
- rollup: "^3.20.2",
343
- uuid: "^9.0.0",
344
- tslib: "^2.5.0",
345
- typescript: "^5.0.2"
346
- };
347
- var devDependencies = {
348
- "@types/prompts": "^2.4.4",
349
- "@types/uuid": "^9.0.1",
350
- "@typescript-eslint/eslint-plugin": "^5.57.0",
351
- "@typescript-eslint/parser": "^5.57.0",
352
- ava: "^5.2.0",
353
- eslint: "^8.37.0",
354
- prettier: "^2.8.7",
355
- "rollup-plugin-visualizer": "^5.9.0",
356
- "ts-node": "^10.9.1",
357
- "tsconfig-paths": "^4.1.2"
358
- };
359
- var ava = {
360
- extensions: [
361
- "ts"
362
- ],
363
- require: [
364
- "ts-node/register",
365
- "tsconfig-paths/register"
366
- ]
367
- };
368
- var cfg = {
369
- name: name,
370
- version: version,
371
- description: description,
372
- author: author,
373
- homepage: homepage,
374
- license: license,
375
- bin: bin,
376
- repository: repository,
377
- engines: engines,
378
- pepr: pepr,
379
- scripts: scripts,
380
- dependencies: dependencies,
381
- devDependencies: devDependencies,
382
- ava: ava
383
- };
384
-
385
- const { Register, ProcessRequest } = new PeprModule(cfg, {
386
- alwaysIgnore: {
387
- namespaces: [],
388
- labels: [],
389
- },
390
- });
391
-
392
- exports.ProcessRequest = ProcessRequest;
393
- exports.Register = Register;
@@ -1,88 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
-
4
- // @todo: quick and dirty temp tls chain for testing, to be replaced at runtime
5
- // Don't freak out, this is a self-signed cert for testing purposes only.
6
-
7
- export function tlsCert() {
8
- return Buffer.from(
9
- `-----BEGIN CERTIFICATE-----
10
- MIIDgzCCAmugAwIBAgIRALguxABI0Iy914FcdkM7B7EwDQYJKoZIhvcNAQELBQAw
11
- NzEXMBUGA1UEChMOWmFyZiBDb21tdW5pdHkxHDAaBgNVBAMTE2NhLnByaXZhdGUu
12
- emFyZi5kZXYwHhcNMjMwMzMxMjMyMTUxWhcNMjQwNDA5MjMyMTUxWjA8MRUwEwYD
13
- VQQKEwxaYXJmIENsdXN0ZXIxIzAhBgNVBAMTGmNvbnRyb2xsZXIucGVwci1zeXN0
14
- ZW0uc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6s7JQyXdZrj
15
- uobjqbZEdh2VRnWaVhdYnWGOB3jguWXrBTTRmPhPuKx9X+ORFrDftG5cGkDp3okC
16
- YGimun932Vi/nmwIc2Q1EAvmaj7LbPDPR4J8RUAO3pqsJijUULmXhrkLgdUxAIY5
17
- srFtuLdaEh0VSc8YUDtbBP3dagDIe+v9eHVS1/ayiv/Tfscm7Mk3NQzvmQfJ5Vt5
18
- K9At+9k7gfV//vBd7SoTJ4uowL+XgyIgF0jIHjHRAX9eR3ew8yly9Sp1K6gEt/oQ
19
- 8pQ8wS37/Dhb3FOQQ5owB1hem1hvdK9qtbwClyzUU/o4RODPcrl/k4MADrGi3wcq
20
- n+FpiwlLLQIDAQABo4GEMIGBMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
21
- BgEFBQcDATAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFIARVhDhiMNYF+0KwIgA
22
- AhO2gLlRMCsGA1UdEQQkMCKCGmNvbnRyb2xsZXIucGVwci1zeXN0ZW0uc3ZjhwR/
23
- AAABMA0GCSqGSIb3DQEBCwUAA4IBAQBsJN3H67/YTl8jQHgsU5sY65u0KlDcxL/v
24
- vDDx807P4ohTa6dLl/mXZD6swN7W0O1oDCgVtTWjAB10UrcLlvs6yos8V4ENzqhM
25
- DaUMwsQSXKCIH/VKaJecpt23SCGYoPZuYBh4PkYwdzBYIQPykV5NdMf02t5DONN+
26
- 08Cj+sE8ESpM3SyTpAAqaJfI+CFzNho8yq3e/zjrswG0FbjZCmG6fitNCCj6G4p1
27
- lOmt+yadVUqov483l09JKUHTut+UsIf91XLCEfon+ajU/IObWDk9sqW8tCFBxhiq
28
- 5Ub2jDZ/hw/3RQHZfP69c1rFRIHMy/ci8cfk6PMg+d4rsNll6kYI
29
- -----END CERTIFICATE-----`
30
- ).toString("base64");
31
- }
32
-
33
- export function tlsKey() {
34
- return Buffer.from(
35
- `-----BEGIN RSA PRIVATE KEY-----
36
- MIIEpQIBAAKCAQEAt6s7JQyXdZrjuobjqbZEdh2VRnWaVhdYnWGOB3jguWXrBTTR
37
- mPhPuKx9X+ORFrDftG5cGkDp3okCYGimun932Vi/nmwIc2Q1EAvmaj7LbPDPR4J8
38
- RUAO3pqsJijUULmXhrkLgdUxAIY5srFtuLdaEh0VSc8YUDtbBP3dagDIe+v9eHVS
39
- 1/ayiv/Tfscm7Mk3NQzvmQfJ5Vt5K9At+9k7gfV//vBd7SoTJ4uowL+XgyIgF0jI
40
- HjHRAX9eR3ew8yly9Sp1K6gEt/oQ8pQ8wS37/Dhb3FOQQ5owB1hem1hvdK9qtbwC
41
- lyzUU/o4RODPcrl/k4MADrGi3wcqn+FpiwlLLQIDAQABAoIBAAxt3wPD1WAVCkIu
42
- LKvodLuVhuuMu9QFom6MEoN476Q8PGpOx7xVWXfC3H0ntkLV112rdjokmG8B0JJb
43
- oqTOSXsA4X7ECtJcPqcGVyJre3K03SIWt3gsPJVd3DZ83tlTpehtD1VK6xUBAFiS
44
- Xz130vWU2EL1a8zKJ3+v+lLZGLgiA8smdUSa3eOCC6nNbPQb8v2d8qRy0f/VaQE8
45
- PtjKaMRK+3pSz2wuWXnGC0rerjyANs1zpDP/ZbQ3gqZ/NGi91E5JueCyZeIA/Rw3
46
- XtEwxoN66OFrdONortUvTgPvpITLKQiL/kK7BX5jX0xAQQtKyd6uL2fWMHcg/AQz
47
- D7T4+dUCgYEA6FJfBPu1505UZxsOvgpCN8qCt+NKF8QW+m90Bvfx7NQcVH/8iYq9
48
- 7biR6fBTWWlNjwqlZ+jl1L50HP3gaZ95rjOfJYFQ47XESDVjOoVNfZWBx7c410or
49
- kx9wOLUv21GGndxIlcsTUSJZ9S++rBjFZfPPSmfmMA/GTusTfkiJS1MCgYEAymNu
50
- ibcSagKpgjesPosVRz+KQqeDt2cWnWgvlfTD8urRY/0eGObZ9Fy0iDamtaJRhMYT
51
- UenvIHntBBnc1wBvzyOrveQpnCpkeaWrqt38VUm2RO4w0ANxXqF6LMEQBTDbsVUm
52
- JTyzRc+e5RL3O63Gx0jEu5iAvOg4pznK+wQev38CgYEAvm9u9i3CsUVTCGV0kzDj
53
- kMoOlt/YR1z0nPqpOGEcTU6dnmJ/RtuUzn1iFkpqeDtKWTuX1HJjmx03HuC4iLwx
54
- ySsFhH/ZJ59CsxIYMcs9dvkLtgMps8hXqbS2j7Vt8jCE0XfVg/w/7FzlMoedm4J+
55
- pRDS1aIPXUxA+UXW58hbyoMCgYEAv2BEfx7I38uCpCqmykFULpor0Bl82Kk3XkLN
56
- dHwN6h8XPvhzRFLO2F3tLDyZaXmCog126WdPAiOo9s7J39h+4Z02YgplOlFvzwPU
57
- j273k2JvY0DkkV4gDr6cu8MXtgDcTRRaTK3YS3QnKS/E7v7Ez17FASsU2QyxvZdN
58
- lAzyUlsCgYEA6A3UAY/gdxtwGf0kAb/hsHPaZLE8dJk7V6k9AUpgiC+sXEr3hLOe
59
- f5FVCDgseP0vWtRLytYbNZSNkW07RIpJV0tE98E7iUVt41NJD1QPRLOSZEAuwkDi
60
- yfYC8xiJwEHBEDTCnKYEyvB6be3zXssGzhp1dbtYILkheEkaewfP5ks=
61
- -----END RSA PRIVATE KEY-----`
62
- ).toString("base64");
63
- }
64
-
65
- export function tlsCA() {
66
- return Buffer.from(
67
- `-----BEGIN CERTIFICATE-----
68
- MIIDWTCCAkGgAwIBAgIQb32UoSCN8rk1nBF3YcWU6zANBgkqhkiG9w0BAQsFADA3
69
- MRcwFQYDVQQKEw5aYXJmIENvbW11bml0eTEcMBoGA1UEAxMTY2EucHJpdmF0ZS56
70
- YXJmLmRldjAeFw0yMzAzMzEyMzIxNTBaFw0yNDA0MDkyMzIxNTBaMDcxFzAVBgNV
71
- BAoTDlphcmYgQ29tbXVuaXR5MRwwGgYDVQQDExNjYS5wcml2YXRlLnphcmYuZGV2
72
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuBDS+q67EPRR0pGFNWxd
73
- JaM2qFWlsjmS8RPiSGmLrRrtLkYDhOUK+PlZLT7Gww/kGPrC/Jq+NSbKt7gDdbrr
74
- 1dBo4tSMFNG0DpcR5JVLGayU1qOBCVoM0kGSJ2U4w9q475rbogb+k+/nnwHCjfTN
75
- fN/78c4Tg6ZKGc0ChXbEPduVmku0qrFwV70Cx6rNjsGT7o5E84NJ/SEZEKsv9DXz
76
- R6Padsnc7291XmyOqyoV4hOwbP6Xs2ZySefVkBm3JuT5brD6BXp/One9PjzeQHtP
77
- Ito1dOnpiCXFS4GTkEJ3slTMFPpxnImgn3+rgr3a8Pq5ICqfheEtCUeLlayKohO2
78
- uwIDAQABo2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
79
- CCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIARVhDhiMNYF+0K
80
- wIgAAhO2gLlRMA0GCSqGSIb3DQEBCwUAA4IBAQBCeISg2fAvgUm+LCxE0An5ZwUw
81
- knO+vTjxeEQXxH4xQjz5Hpj3MQaXFvH2XAhbTAYQl8pKNWcN7vyl/5O8u+AjdDVD
82
- 3TQv5TxQK7gs8YmC1LMc66aFSYHruqCD14PiwaQqD8Rzz8/nGwqvCD3K6vDsyvC4
83
- anUV/tzbMU/hwCn6uw+S/LgM4xQIllccGX1cJC7pSZJNiTzmhWEfKpOVrUoTEQqf
84
- tyAwSSHdPz5EhuDybxhOhh00lQG5POY6UGYqKKR1uoXXniqGXXjIqUeiA6FjEMYC
85
- 4V//uhn+NeiPo1VtU7sCZfxT4x/qSy/bSSdB3qADqmgWhRHelJPe2TlBmCDx
86
- -----END CERTIFICATE-----`
87
- ).toString("base64");
88
- }