@firestartr/cli 2.7.0-snapshot-21 → 2.7.0-snapshot-22
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/build/index.js +439 -120
- package/build/packages/gh_provisioner/src/entities/ghfeature/index.d.ts +1 -1
- package/build/packages/gh_provisioner/src/tp_bridge.d.ts +1 -0
- package/build/packages/operator/index.d.ts +1 -0
- package/build/packages/operator/src/connection.d.ts +5 -0
- package/build/packages/operator/src/ctl.d.ts +2 -4
- package/build/packages/operator/src/diagnosticErrors.d.ts +2 -0
- package/build/packages/operator/src/processItem.diagnostic.d.ts +5 -0
- package/build/packages/operator/src/utils/api-read-limiter.d.ts +10 -0
- package/build/packages/operator/src/utils/semaphore.d.ts +15 -0
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -330867,6 +330867,138 @@ function getOperatorEnvSnapshot() {
|
|
|
330867
330867
|
return { ...snapshot };
|
|
330868
330868
|
}
|
|
330869
330869
|
|
|
330870
|
+
;// CONCATENATED MODULE: ../operator/src/connection.ts
|
|
330871
|
+
|
|
330872
|
+
|
|
330873
|
+
async function connection_getConnection() {
|
|
330874
|
+
try {
|
|
330875
|
+
const kc = new client_node_dist.KubeConfig();
|
|
330876
|
+
kc.loadFromDefault();
|
|
330877
|
+
const opts = {};
|
|
330878
|
+
await kc.applyToHTTPSOptions(opts);
|
|
330879
|
+
return { kc, opts };
|
|
330880
|
+
}
|
|
330881
|
+
catch (err) {
|
|
330882
|
+
operator_src_logger.error(`getConnection: ${err}`);
|
|
330883
|
+
throw err;
|
|
330884
|
+
}
|
|
330885
|
+
}
|
|
330886
|
+
|
|
330887
|
+
;// CONCATENATED MODULE: ../operator/src/utils/semaphore.ts
|
|
330888
|
+
class Semaphore {
|
|
330889
|
+
constructor(max) {
|
|
330890
|
+
this._current = 0;
|
|
330891
|
+
this._queue = [];
|
|
330892
|
+
this._totalAcquisitions = 0;
|
|
330893
|
+
this._timesSaturated = 0;
|
|
330894
|
+
if (!Number.isFinite(max) || Number.isNaN(max) || max < 1) {
|
|
330895
|
+
throw new Error(`Semaphore max must be a finite number >= 1: ${max}`);
|
|
330896
|
+
}
|
|
330897
|
+
this._max = Math.floor(max);
|
|
330898
|
+
}
|
|
330899
|
+
get max() {
|
|
330900
|
+
return this._max;
|
|
330901
|
+
}
|
|
330902
|
+
get current() {
|
|
330903
|
+
return this._current;
|
|
330904
|
+
}
|
|
330905
|
+
get waiting() {
|
|
330906
|
+
return this._queue.length;
|
|
330907
|
+
}
|
|
330908
|
+
get totalAcquisitions() {
|
|
330909
|
+
return this._totalAcquisitions;
|
|
330910
|
+
}
|
|
330911
|
+
get timesSaturated() {
|
|
330912
|
+
return this._timesSaturated;
|
|
330913
|
+
}
|
|
330914
|
+
async acquire() {
|
|
330915
|
+
if (this._current < this._max) {
|
|
330916
|
+
this._current++;
|
|
330917
|
+
this._totalAcquisitions++;
|
|
330918
|
+
return;
|
|
330919
|
+
}
|
|
330920
|
+
this._timesSaturated++;
|
|
330921
|
+
await new Promise((resolve) => {
|
|
330922
|
+
this._queue.push(() => {
|
|
330923
|
+
this._current++;
|
|
330924
|
+
this._totalAcquisitions++;
|
|
330925
|
+
resolve();
|
|
330926
|
+
});
|
|
330927
|
+
});
|
|
330928
|
+
}
|
|
330929
|
+
release() {
|
|
330930
|
+
if (this._current <= 0) {
|
|
330931
|
+
this._current = 0;
|
|
330932
|
+
return;
|
|
330933
|
+
}
|
|
330934
|
+
this._current--;
|
|
330935
|
+
const next = this._queue.shift();
|
|
330936
|
+
if (next) {
|
|
330937
|
+
next();
|
|
330938
|
+
}
|
|
330939
|
+
}
|
|
330940
|
+
}
|
|
330941
|
+
|
|
330942
|
+
;// CONCATENATED MODULE: ../operator/src/utils/api-read-limiter.ts
|
|
330943
|
+
|
|
330944
|
+
const DEFAULT_MAX_CONCURRENT_API_CALLS = 50;
|
|
330945
|
+
const MIN_CONCURRENT_API_CALLS_PER_SLOT = 4;
|
|
330946
|
+
function parseMaxSlots(value) {
|
|
330947
|
+
if (value === undefined)
|
|
330948
|
+
return 1;
|
|
330949
|
+
const parsed = Number(value);
|
|
330950
|
+
const floored = Math.floor(parsed);
|
|
330951
|
+
if (!Number.isFinite(parsed) || Number.isNaN(parsed) || floored < 1)
|
|
330952
|
+
return 1;
|
|
330953
|
+
return floored;
|
|
330954
|
+
}
|
|
330955
|
+
function computeMaxConcurrentApiCalls(rawMaxConcurrent, rawMaxSlots) {
|
|
330956
|
+
const maxSlots = parseMaxSlots(rawMaxSlots);
|
|
330957
|
+
const minRequired = maxSlots * MIN_CONCURRENT_API_CALLS_PER_SLOT;
|
|
330958
|
+
if (rawMaxConcurrent === undefined) {
|
|
330959
|
+
return Math.max(DEFAULT_MAX_CONCURRENT_API_CALLS, minRequired);
|
|
330960
|
+
}
|
|
330961
|
+
const parsed = Number(rawMaxConcurrent);
|
|
330962
|
+
const floored = Math.floor(parsed);
|
|
330963
|
+
if (!Number.isFinite(parsed) || Number.isNaN(parsed) || floored < 1) {
|
|
330964
|
+
return Math.max(DEFAULT_MAX_CONCURRENT_API_CALLS, minRequired);
|
|
330965
|
+
}
|
|
330966
|
+
return Math.max(floored, minRequired);
|
|
330967
|
+
}
|
|
330968
|
+
const apiReadSemaphore = new Semaphore(computeMaxConcurrentApiCalls(process.env.OPERATOR_MAX_CONCURRENT_API_CALLS, process.env.OPERATOR_NUMBER_OF_MAX_SLOTS));
|
|
330969
|
+
let _peakConcurrentApiCalls = 0;
|
|
330970
|
+
async function withApiReadSlot(read) {
|
|
330971
|
+
await apiReadSemaphore.acquire();
|
|
330972
|
+
const current = apiReadSemaphore.current;
|
|
330973
|
+
if (current > _peakConcurrentApiCalls) {
|
|
330974
|
+
_peakConcurrentApiCalls = current;
|
|
330975
|
+
}
|
|
330976
|
+
try {
|
|
330977
|
+
return await read();
|
|
330978
|
+
}
|
|
330979
|
+
finally {
|
|
330980
|
+
apiReadSemaphore.release();
|
|
330981
|
+
}
|
|
330982
|
+
}
|
|
330983
|
+
function getPeakConcurrentApiCalls() {
|
|
330984
|
+
return _peakConcurrentApiCalls;
|
|
330985
|
+
}
|
|
330986
|
+
function getCurrentConcurrentApiCalls() {
|
|
330987
|
+
return apiReadSemaphore.current;
|
|
330988
|
+
}
|
|
330989
|
+
function getPendingApiCalls() {
|
|
330990
|
+
return apiReadSemaphore.waiting;
|
|
330991
|
+
}
|
|
330992
|
+
function getMaxConcurrentApiCalls() {
|
|
330993
|
+
return apiReadSemaphore.max;
|
|
330994
|
+
}
|
|
330995
|
+
function getTotalApiAcquisitions() {
|
|
330996
|
+
return apiReadSemaphore.totalAcquisitions;
|
|
330997
|
+
}
|
|
330998
|
+
function getTimesSemaphoreSaturated() {
|
|
330999
|
+
return apiReadSemaphore.timesSaturated;
|
|
331000
|
+
}
|
|
331001
|
+
|
|
330870
331002
|
;// CONCATENATED MODULE: ../operator/src/ctl.ts
|
|
330871
331003
|
|
|
330872
331004
|
|
|
@@ -330876,6 +331008,8 @@ function getOperatorEnvSnapshot() {
|
|
|
330876
331008
|
|
|
330877
331009
|
|
|
330878
331010
|
|
|
331011
|
+
|
|
331012
|
+
|
|
330879
331013
|
const MAX_CHARS_OUPUT_PLAN = 20000;
|
|
330880
331014
|
function getOperatorProfile() {
|
|
330881
331015
|
github["default"].createProfile('operator', {
|
|
@@ -330888,29 +331022,33 @@ async function getItem(kind, namespace, item) {
|
|
|
330888
331022
|
const itemPath = `${namespace}/${kind}/${item.metadata.name}`;
|
|
330889
331023
|
return await ctl_getItemByItemPath(itemPath);
|
|
330890
331024
|
}
|
|
331025
|
+
async function fetchItemByItemPathResponse(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
|
|
331026
|
+
operator_src_logger.debug(`The ctl is getting the item at '${itemPath}'.`);
|
|
331027
|
+
const { kc, opts } = await connection_getConnection();
|
|
331028
|
+
opts.headers['Content-Type'] = 'application/json';
|
|
331029
|
+
opts.headers['Accept'] = 'application/json';
|
|
331030
|
+
const url = apiGroup === catalog_common/* default.types.controller.KubernetesApiGroup */.Z.types.controller.KubernetesApiGroup
|
|
331031
|
+
? `${kc.getCurrentCluster().server}/api/v1/namespaces/${itemPath}`
|
|
331032
|
+
: `${kc.getCurrentCluster().server}/apis/${apiGroup}/${apiVersion}/namespaces/${itemPath}`;
|
|
331033
|
+
operator_src_logger.silly(`Sending request ${url}`);
|
|
331034
|
+
return await fetch(url, { method: 'get', headers: opts.headers });
|
|
331035
|
+
}
|
|
330891
331036
|
async function ctl_getItemByItemPath(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
|
|
330892
|
-
|
|
330893
|
-
|
|
330894
|
-
|
|
330895
|
-
|
|
330896
|
-
|
|
330897
|
-
|
|
330898
|
-
|
|
330899
|
-
|
|
330900
|
-
|
|
330901
|
-
const r = await fetch(url, { method: 'get', headers: opts.headers });
|
|
330902
|
-
if (!r.ok) {
|
|
330903
|
-
const err = new Error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
330904
|
-
operator_src_logger.error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
330905
|
-
throw err;
|
|
331037
|
+
return await withApiReadSlot(async () => {
|
|
331038
|
+
try {
|
|
331039
|
+
const r = await fetchItemByItemPathResponse(itemPath, apiGroup, apiVersion);
|
|
331040
|
+
if (!r.ok) {
|
|
331041
|
+
const err = new Error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
331042
|
+
operator_src_logger.error(`Error on getItemByItemPath: ${itemPath}: ${r.statusText}`);
|
|
331043
|
+
throw err;
|
|
331044
|
+
}
|
|
331045
|
+
return await r.json();
|
|
330906
331046
|
}
|
|
330907
|
-
|
|
330908
|
-
|
|
330909
|
-
|
|
330910
|
-
|
|
330911
|
-
|
|
330912
|
-
throw e;
|
|
330913
|
-
}
|
|
331047
|
+
catch (e) {
|
|
331048
|
+
operator_src_logger.error(`Error on getItemByItemPath: ${e}`);
|
|
331049
|
+
throw e;
|
|
331050
|
+
}
|
|
331051
|
+
});
|
|
330914
331052
|
}
|
|
330915
331053
|
/**
|
|
330916
331054
|
* Like getItemByItemPath but returns null when the resource is not found
|
|
@@ -330919,34 +331057,28 @@ async function ctl_getItemByItemPath(itemPath, apiGroup = catalog_common/* defau
|
|
|
330919
331057
|
* whether a parent CR has been provisioned before its children arrive).
|
|
330920
331058
|
*/
|
|
330921
331059
|
async function getItemByItemPathOrNull(itemPath, apiGroup = catalog_common/* default.types.controller.FirestartrApiGroup */.Z.types.controller.FirestartrApiGroup, apiVersion = 'v1') {
|
|
330922
|
-
|
|
330923
|
-
|
|
330924
|
-
|
|
330925
|
-
|
|
330926
|
-
|
|
330927
|
-
|
|
330928
|
-
|
|
330929
|
-
|
|
330930
|
-
|
|
330931
|
-
|
|
330932
|
-
|
|
330933
|
-
|
|
330934
|
-
return
|
|
331060
|
+
return await withApiReadSlot(async () => {
|
|
331061
|
+
try {
|
|
331062
|
+
const r = await fetchItemByItemPathResponse(itemPath, apiGroup, apiVersion);
|
|
331063
|
+
if (r.status === 404 || r.status === 409) {
|
|
331064
|
+
operator_src_logger.debug(`Item at '${itemPath}' returned ${r.status} (expected), returning null.`);
|
|
331065
|
+
return null;
|
|
331066
|
+
}
|
|
331067
|
+
if (!r.ok) {
|
|
331068
|
+
const err = new Error(`Error on getItemByItemPathOrNull: ${itemPath}: ${r.statusText}`);
|
|
331069
|
+
operator_src_logger.error(`Error on getItemByItemPathOrNull: ${itemPath}: ${r.statusText}`);
|
|
331070
|
+
throw err;
|
|
331071
|
+
}
|
|
331072
|
+
return await r.json();
|
|
330935
331073
|
}
|
|
330936
|
-
|
|
330937
|
-
|
|
330938
|
-
|
|
330939
|
-
throw err;
|
|
331074
|
+
catch (e) {
|
|
331075
|
+
operator_src_logger.error(`Error on getItemByItemPathOrNull: ${e}`);
|
|
331076
|
+
throw e;
|
|
330940
331077
|
}
|
|
330941
|
-
|
|
330942
|
-
}
|
|
330943
|
-
catch (e) {
|
|
330944
|
-
operator_src_logger.error(`Error on getItemByItemPath: ${e}`);
|
|
330945
|
-
throw e;
|
|
330946
|
-
}
|
|
331078
|
+
});
|
|
330947
331079
|
}
|
|
330948
331080
|
async function writeManifest(kind, namespace, item, apiSlug) {
|
|
330949
|
-
const { kc, opts } = await
|
|
331081
|
+
const { kc, opts } = await connection_getConnection();
|
|
330950
331082
|
opts.headers['Content-Type'] = 'application/json';
|
|
330951
331083
|
opts.headers['Accept'] = 'application/json';
|
|
330952
331084
|
const r = await fetch(`${kc.getCurrentCluster().server}/${apiSlug}`, {
|
|
@@ -331028,19 +331160,8 @@ function helperIsValidJSON(part) {
|
|
|
331028
331160
|
return false;
|
|
331029
331161
|
}
|
|
331030
331162
|
}
|
|
331031
|
-
|
|
331032
|
-
|
|
331033
|
-
const kc = new client_node_dist.KubeConfig();
|
|
331034
|
-
kc.loadFromDefault();
|
|
331035
|
-
const opts = {};
|
|
331036
|
-
await kc.applyToHTTPSOptions(opts);
|
|
331037
|
-
return { kc, opts };
|
|
331038
|
-
}
|
|
331039
|
-
catch (err) {
|
|
331040
|
-
operator_src_logger.error(`getConnection: ${err}`);
|
|
331041
|
-
throw err;
|
|
331042
|
-
}
|
|
331043
|
-
}
|
|
331163
|
+
|
|
331164
|
+
|
|
331044
331165
|
function buildTFResultStatusUpdate(namespace, tfResultName, resourceVersion, exitCode, retryCount) {
|
|
331045
331166
|
const status = {
|
|
331046
331167
|
exitCode: exitCode,
|
|
@@ -331074,7 +331195,7 @@ async function tryWriteTFResultStatus(namespace, tfResultName, resourceVersion,
|
|
|
331074
331195
|
}
|
|
331075
331196
|
}
|
|
331076
331197
|
async function upsertResult(namespace, item, result, exitCode = 0, existingRetryCount) {
|
|
331077
|
-
const { kc, opts } = await
|
|
331198
|
+
const { kc, opts } = await connection_getConnection();
|
|
331078
331199
|
kc.makeApiClient(client_node_dist.CoreV1Api);
|
|
331079
331200
|
const exists = await getTFResult(namespace, item);
|
|
331080
331201
|
const currentRetryCount = existingRetryCount !== undefined
|
|
@@ -331129,7 +331250,7 @@ async function upsertResult(namespace, item, result, exitCode = 0, existingRetry
|
|
|
331129
331250
|
}
|
|
331130
331251
|
}
|
|
331131
331252
|
async function deleteSecret(secretName, namespace) {
|
|
331132
|
-
const { kc } = await
|
|
331253
|
+
const { kc } = await connection_getConnection();
|
|
331133
331254
|
const k8sApi = kc.makeApiClient(client_node_dist.CoreV1Api);
|
|
331134
331255
|
try {
|
|
331135
331256
|
await k8sApi.deleteNamespacedSecret(secretName, namespace);
|
|
@@ -331145,7 +331266,7 @@ async function deleteSecret(secretName, namespace) {
|
|
|
331145
331266
|
}
|
|
331146
331267
|
}
|
|
331147
331268
|
async function upsertSecret(namespace, secret) {
|
|
331148
|
-
const { kc } = await
|
|
331269
|
+
const { kc } = await connection_getConnection();
|
|
331149
331270
|
const k8sApi = kc.makeApiClient(client_node_dist.CoreV1Api);
|
|
331150
331271
|
secret.metadata.name = secret.metadata.name.toLowerCase();
|
|
331151
331272
|
try {
|
|
@@ -331162,7 +331283,7 @@ async function upsertSecret(namespace, secret) {
|
|
|
331162
331283
|
}
|
|
331163
331284
|
}
|
|
331164
331285
|
async function getSecret(namespace, secretName) {
|
|
331165
|
-
const { kc } = await
|
|
331286
|
+
const { kc } = await connection_getConnection();
|
|
331166
331287
|
const k8sApi = kc.makeApiClient(client_node_dist.CoreV1Api);
|
|
331167
331288
|
try {
|
|
331168
331289
|
const secret = await k8sApi.readNamespacedSecret(secretName, namespace);
|
|
@@ -331179,7 +331300,7 @@ async function getSecret(namespace, secretName) {
|
|
|
331179
331300
|
}
|
|
331180
331301
|
}
|
|
331181
331302
|
async function getTFResult(namespace, item) {
|
|
331182
|
-
const { kc, opts } = await
|
|
331303
|
+
const { kc, opts } = await connection_getConnection();
|
|
331183
331304
|
opts.headers['Content-Type'] = 'application/json';
|
|
331184
331305
|
opts.headers['Accept'] = 'application/json';
|
|
331185
331306
|
const r = await fetch(`${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/tfresults/${item.kind}-${item.metadata.name}`.toLowerCase(), {
|
|
@@ -331209,7 +331330,7 @@ async function checkIfRenamed(namespace, item) {
|
|
|
331209
331330
|
try {
|
|
331210
331331
|
// Check that the old item still exists
|
|
331211
331332
|
const plural = getPluralFromKind(item.kind);
|
|
331212
|
-
const { kc, opts } = await
|
|
331333
|
+
const { kc, opts } = await getCtlConnection();
|
|
331213
331334
|
const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${plural}/${item.metadata.name}`;
|
|
331214
331335
|
const r = await fetch(url, {
|
|
331215
331336
|
method: 'GET',
|
|
@@ -331230,7 +331351,7 @@ async function checkIfRenamed(namespace, item) {
|
|
|
331230
331351
|
}
|
|
331231
331352
|
}
|
|
331232
331353
|
async function upsertFinalizer(kind, namespace, item, finalizer) {
|
|
331233
|
-
const { kc, opts } = await
|
|
331354
|
+
const { kc, opts } = await connection_getConnection();
|
|
331234
331355
|
const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${item.metadata.name}`;
|
|
331235
331356
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
331236
331357
|
// Fresh GET to get current finalizers and resourceVersion
|
|
@@ -331286,7 +331407,7 @@ async function upsertFinalizer(kind, namespace, item, finalizer) {
|
|
|
331286
331407
|
* @returns {void}
|
|
331287
331408
|
*/
|
|
331288
331409
|
async function unsetFinalizer(kind, namespace, item, finalizer) {
|
|
331289
|
-
const { kc, opts } = await
|
|
331410
|
+
const { kc, opts } = await connection_getConnection();
|
|
331290
331411
|
let itemObj;
|
|
331291
331412
|
if (typeof item === 'string') {
|
|
331292
331413
|
itemObj = await ctl_getItemByItemPath([namespace, kind, item].join('/'));
|
|
@@ -331457,7 +331578,7 @@ async function addCommitStatusToPrMergeCommit(prAnnotationValue, state, targetUR
|
|
|
331457
331578
|
await getOperatorProfile().repo.addCommitStatus(state, branchSha, repo, owner, targetURL, description, context);
|
|
331458
331579
|
}
|
|
331459
331580
|
async function createDryRun(manifest, namespace) {
|
|
331460
|
-
const { kc } = await
|
|
331581
|
+
const { kc } = await connection_getConnection();
|
|
331461
331582
|
const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
331462
331583
|
const plural = definitions_getPluralFromKind(manifest.kind);
|
|
331463
331584
|
if (!plural)
|
|
@@ -331465,7 +331586,7 @@ async function createDryRun(manifest, namespace) {
|
|
|
331465
331586
|
await k8sApi.createNamespacedCustomObject('firestartr.dev', 'v1', namespace, plural, manifest, undefined, 'All');
|
|
331466
331587
|
}
|
|
331467
331588
|
async function updateDryRun(manifest, namespace) {
|
|
331468
|
-
const { kc } = await
|
|
331589
|
+
const { kc } = await connection_getConnection();
|
|
331469
331590
|
const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
331470
331591
|
const plural = definitions_getPluralFromKind(manifest.kind);
|
|
331471
331592
|
if (!plural)
|
|
@@ -331489,7 +331610,7 @@ async function updateDryRun(manifest, namespace) {
|
|
|
331489
331610
|
*/
|
|
331490
331611
|
async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename) {
|
|
331491
331612
|
const store = new Store(plural);
|
|
331492
|
-
const { kc } = await
|
|
331613
|
+
const { kc } = await connection_getConnection();
|
|
331493
331614
|
try {
|
|
331494
331615
|
const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
331495
331616
|
const apiGroup = 'firestartr.dev';
|
|
@@ -331870,10 +331991,10 @@ async function getSyncSpecs(itemPath, itemCR) {
|
|
|
331870
331991
|
return {
|
|
331871
331992
|
item,
|
|
331872
331993
|
syncable: helperIsSyncable(item),
|
|
331873
|
-
period: item.metadata.annotations['firestartr.dev/sync-period'] ||
|
|
331994
|
+
period: item.metadata.annotations?.['firestartr.dev/sync-period'] ||
|
|
331874
331995
|
DEFAULT_REVISION_TIME,
|
|
331875
|
-
schedule: item.metadata.annotations['firestartr.dev/sync-schedule'] || false,
|
|
331876
|
-
scheduleTZ: item.metadata.annotations['firestartr.dev/sync-schedule-timezone'] ||
|
|
331996
|
+
schedule: item.metadata.annotations?.['firestartr.dev/sync-schedule'] || false,
|
|
331997
|
+
scheduleTZ: item.metadata.annotations?.['firestartr.dev/sync-schedule-timezone'] ||
|
|
331877
331998
|
'Europe/Madrid',
|
|
331878
331999
|
};
|
|
331879
332000
|
}
|
|
@@ -331924,7 +332045,7 @@ function assessSyncCalculationMachinery(item) {
|
|
|
331924
332045
|
if (!helperIsSyncable(item)) {
|
|
331925
332046
|
return processNotSyncable;
|
|
331926
332047
|
}
|
|
331927
|
-
else if (item.metadata.annotations['firestartr.dev/sync-schedule'] ??
|
|
332048
|
+
else if (item.metadata.annotations?.['firestartr.dev/sync-schedule'] ??
|
|
331928
332049
|
false) {
|
|
331929
332050
|
return processScheduledSync;
|
|
331930
332051
|
}
|
|
@@ -331953,7 +332074,8 @@ async function processNotSyncable(item, reason, status, message) {
|
|
|
331953
332074
|
};
|
|
331954
332075
|
}
|
|
331955
332076
|
async function processPeriodSync(item, reason, status, message) {
|
|
331956
|
-
const period = item.metadata.annotations['firestartr.dev/sync-period']
|
|
332077
|
+
const period = item.metadata.annotations?.['firestartr.dev/sync-period'] ||
|
|
332078
|
+
DEFAULT_REVISION_TIME;
|
|
331957
332079
|
const periodMS = helperCalculateRevisionTime(period);
|
|
331958
332080
|
return {
|
|
331959
332081
|
syncMode: 'Period',
|
|
@@ -331983,7 +332105,7 @@ function helperCalculateRevisionTime(period) {
|
|
|
331983
332105
|
return Number(scalar) * multiplier * 1000;
|
|
331984
332106
|
}
|
|
331985
332107
|
async function processScheduledSync(item, reason, status, message) {
|
|
331986
|
-
const nextPeriod = catalog_common/* default.cron.getCronNextInterval */.Z.cron.getCronNextInterval(item.metadata.annotations['firestartr.dev/sync-schedule'], item.metadata.annotations['firestartr.dev/sync-schedule-timezone'] ||
|
|
332108
|
+
const nextPeriod = catalog_common/* default.cron.getCronNextInterval */.Z.cron.getCronNextInterval(item.metadata.annotations?.['firestartr.dev/sync-schedule'], item.metadata.annotations?.['firestartr.dev/sync-schedule-timezone'] ||
|
|
331987
332109
|
undefined);
|
|
331988
332110
|
const nextPeriodDate = new Date(nextPeriod);
|
|
331989
332111
|
return {
|
|
@@ -332888,7 +333010,7 @@ async function* traverseCRCollection(pluralKind, namespace, options = {}, apiGro
|
|
|
332888
333010
|
const { limit = 300 } = options; // between 250-300
|
|
332889
333011
|
try {
|
|
332890
333012
|
let continueToken = undefined;
|
|
332891
|
-
const { kc, opts } = await
|
|
333013
|
+
const { kc, opts } = await connection_getConnection();
|
|
332892
333014
|
const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
332893
333015
|
const apiGroup = 'firestartr.dev';
|
|
332894
333016
|
const apiVersion = 'v1';
|
|
@@ -333462,6 +333584,165 @@ function formatElapsedTimeWithDate(upsertTime) {
|
|
|
333462
333584
|
return `${parts.slice(0, 2).join(', ')} ago`;
|
|
333463
333585
|
}
|
|
333464
333586
|
|
|
333587
|
+
;// CONCATENATED MODULE: ../operator/src/diagnosticErrors.ts
|
|
333588
|
+
/**
|
|
333589
|
+
* Global error counter for the diagnostic file.
|
|
333590
|
+
* Increment-only; never reset during the operator lifetime.
|
|
333591
|
+
*/
|
|
333592
|
+
let _errorCount = 0;
|
|
333593
|
+
function incrementDiagnosticErrorCount() {
|
|
333594
|
+
_errorCount++;
|
|
333595
|
+
}
|
|
333596
|
+
function getDiagnosticErrorCount() {
|
|
333597
|
+
return _errorCount;
|
|
333598
|
+
}
|
|
333599
|
+
|
|
333600
|
+
;// CONCATENATED MODULE: ../operator/src/processItem.diagnostic.ts
|
|
333601
|
+
|
|
333602
|
+
|
|
333603
|
+
|
|
333604
|
+
|
|
333605
|
+
|
|
333606
|
+
const DIAGNOSTIC_FILE = '/tmp/diagnostic';
|
|
333607
|
+
const DIAGNOSTIC_INTERVAL_MS = 10 * 1000;
|
|
333608
|
+
let _diagnosticTimer;
|
|
333609
|
+
function clearTimer() {
|
|
333610
|
+
if (_diagnosticTimer !== undefined) {
|
|
333611
|
+
clearInterval(_diagnosticTimer);
|
|
333612
|
+
_diagnosticTimer = undefined;
|
|
333613
|
+
}
|
|
333614
|
+
}
|
|
333615
|
+
function loopDiagnosticFile(queue, maxSlots) {
|
|
333616
|
+
if (process.env.DISABLE_DIAGNOSTIC_FILE) {
|
|
333617
|
+
operator_src_logger.info('Diagnostic file disabled by DISABLE_DIAGNOSTIC_FILE');
|
|
333618
|
+
return;
|
|
333619
|
+
}
|
|
333620
|
+
let running = false;
|
|
333621
|
+
_diagnosticTimer = setInterval(() => {
|
|
333622
|
+
if (running)
|
|
333623
|
+
return;
|
|
333624
|
+
running = true;
|
|
333625
|
+
writeDiagnosticSnapshot(queue, maxSlots)
|
|
333626
|
+
.then(() => {
|
|
333627
|
+
running = false;
|
|
333628
|
+
})
|
|
333629
|
+
.catch((err) => {
|
|
333630
|
+
running = false;
|
|
333631
|
+
operator_src_logger.error(`Error writing diagnostic file: ${err}`);
|
|
333632
|
+
});
|
|
333633
|
+
}, DIAGNOSTIC_INTERVAL_MS);
|
|
333634
|
+
// Clear the interval on termination signals so the process can exit cleanly
|
|
333635
|
+
const onSignal = () => clearTimer();
|
|
333636
|
+
process.on('SIGTERM', onSignal);
|
|
333637
|
+
process.on('SIGINT', onSignal);
|
|
333638
|
+
}
|
|
333639
|
+
/** @internal for testing */
|
|
333640
|
+
function getDiagnosticTimer() {
|
|
333641
|
+
return _diagnosticTimer;
|
|
333642
|
+
}
|
|
333643
|
+
async function writeDiagnosticSnapshot(queue, maxSlots) {
|
|
333644
|
+
const now = new Date().toISOString();
|
|
333645
|
+
// Queue counts
|
|
333646
|
+
let pending = 0;
|
|
333647
|
+
let processing = 0;
|
|
333648
|
+
let finished = 0;
|
|
333649
|
+
let blocked = 0;
|
|
333650
|
+
let deadLetter = 0;
|
|
333651
|
+
// Per-slot items
|
|
333652
|
+
const slotsMap = {};
|
|
333653
|
+
for (const wi of queue) {
|
|
333654
|
+
switch (wi.workStatus) {
|
|
333655
|
+
case WorkStatus.PENDING:
|
|
333656
|
+
pending++;
|
|
333657
|
+
break;
|
|
333658
|
+
case WorkStatus.PROCESSING:
|
|
333659
|
+
processing++;
|
|
333660
|
+
break;
|
|
333661
|
+
case WorkStatus.FINISHED:
|
|
333662
|
+
finished++;
|
|
333663
|
+
break;
|
|
333664
|
+
}
|
|
333665
|
+
if (wi.isBlocked) {
|
|
333666
|
+
blocked++;
|
|
333667
|
+
}
|
|
333668
|
+
if (wi.isDeadLetter) {
|
|
333669
|
+
deadLetter++;
|
|
333670
|
+
}
|
|
333671
|
+
if (wi.workStatus === WorkStatus.PROCESSING && wi.slotId !== undefined) {
|
|
333672
|
+
slotsMap[`slot-${wi.slotId}`] =
|
|
333673
|
+
`${wi.item.kind}/${wi.item.metadata.name}`;
|
|
333674
|
+
}
|
|
333675
|
+
}
|
|
333676
|
+
// Fill empty slots with null
|
|
333677
|
+
for (let i = 0; i < maxSlots; i++) {
|
|
333678
|
+
if (!slotsMap[`slot-${i}`]) {
|
|
333679
|
+
slotsMap[`slot-${i}`] = 'null';
|
|
333680
|
+
}
|
|
333681
|
+
}
|
|
333682
|
+
// Semaphore stats
|
|
333683
|
+
const semaphoreCurrent = getCurrentConcurrentApiCalls();
|
|
333684
|
+
const semaphoreMax = getMaxConcurrentApiCalls();
|
|
333685
|
+
const semaphorePeak = getPeakConcurrentApiCalls();
|
|
333686
|
+
const semaphorePending = getPendingApiCalls();
|
|
333687
|
+
const semaphoreTotalAcquisitions = getTotalApiAcquisitions();
|
|
333688
|
+
const semaphoreTimesSaturated = getTimesSemaphoreSaturated();
|
|
333689
|
+
// Environment
|
|
333690
|
+
const envMaxSlots = process.env.OPERATOR_NUMBER_OF_MAX_SLOTS || '1';
|
|
333691
|
+
const envMaxConcurrentApi = process.env.OPERATOR_MAX_CONCURRENT_API_CALLS || '25';
|
|
333692
|
+
const envKindList = process.env.OPERATOR_KIND_LIST || '';
|
|
333693
|
+
const envTfmMirrorDisable = process.env.TFM_MIRROR_DISABLE || '0';
|
|
333694
|
+
const envTfmMirrorList = process.env.TFM_MIRROR_LIST || '';
|
|
333695
|
+
const envTfmMirrorRefreshInterval = process.env.TFM_MIRROR_REFRESH_INTERVAL || '900';
|
|
333696
|
+
const envBackendProvider = process.env.BACKEND_PROVIDER_NAME || 'kubernetes-provider';
|
|
333697
|
+
const envGithubAppId = process.env.GITHUB_APP_ID || '';
|
|
333698
|
+
// Build YAML output
|
|
333699
|
+
let output = '';
|
|
333700
|
+
output += `timestamp: "${now}"\n`;
|
|
333701
|
+
output += 'env:\n';
|
|
333702
|
+
output += ` OPERATOR_NUMBER_OF_MAX_SLOTS: ${envMaxSlots}\n`;
|
|
333703
|
+
output += ` OPERATOR_MAX_CONCURRENT_API_CALLS: ${envMaxConcurrentApi}\n`;
|
|
333704
|
+
output += ` OPERATOR_KIND_LIST: ${envKindList}\n`;
|
|
333705
|
+
output += ` TFM_MIRROR_DISABLE: ${envTfmMirrorDisable}\n`;
|
|
333706
|
+
output += ` TFM_MIRROR_LIST: ${envTfmMirrorList}\n`;
|
|
333707
|
+
output += ` TFM_MIRROR_REFRESH_INTERVAL: ${envTfmMirrorRefreshInterval}\n`;
|
|
333708
|
+
output += ` BACKEND_PROVIDER_NAME: ${envBackendProvider}\n`;
|
|
333709
|
+
output += ` GITHUB_APP_ID: ${envGithubAppId}\n`;
|
|
333710
|
+
output += 'queue:\n';
|
|
333711
|
+
output += ` total: ${queue.length}\n`;
|
|
333712
|
+
output += ` pending: ${pending}\n`;
|
|
333713
|
+
output += ` processing: ${processing}\n`;
|
|
333714
|
+
output += ` finished: ${finished}\n`;
|
|
333715
|
+
output += ` blocked: ${blocked}\n`;
|
|
333716
|
+
output += ` dead_letter: ${deadLetter}\n`;
|
|
333717
|
+
output += 'slots:\n';
|
|
333718
|
+
output += ` max: ${maxSlots}\n`;
|
|
333719
|
+
output += ` active: ${processing}\n`;
|
|
333720
|
+
output += ' items_per_slot:\n';
|
|
333721
|
+
for (let i = 0; i < maxSlots; i++) {
|
|
333722
|
+
const key = `slot-${i}`;
|
|
333723
|
+
const val = slotsMap[key];
|
|
333724
|
+
output += ` ${key}: ${val === 'null' ? 'null' : `"${val}"`}\n`;
|
|
333725
|
+
}
|
|
333726
|
+
output += 'semaphore:\n';
|
|
333727
|
+
output += ` max: ${semaphoreMax}\n`;
|
|
333728
|
+
output += ` in_use: ${semaphoreCurrent}\n`;
|
|
333729
|
+
output += ` available: ${semaphoreMax - semaphoreCurrent}\n`;
|
|
333730
|
+
output += ` pending: ${semaphorePending}\n`;
|
|
333731
|
+
output += ` peak: ${semaphorePeak}\n`;
|
|
333732
|
+
output += ` total_acquisitions: ${semaphoreTotalAcquisitions}\n`;
|
|
333733
|
+
output += ` times_saturated: ${semaphoreTimesSaturated}\n`;
|
|
333734
|
+
output += 'errors:\n';
|
|
333735
|
+
output += ` total: ${getDiagnosticErrorCount()}\n`;
|
|
333736
|
+
return new Promise((resolve, reject) => {
|
|
333737
|
+
external_fs_.writeFile(DIAGNOSTIC_FILE, output, (err) => {
|
|
333738
|
+
if (err)
|
|
333739
|
+
reject(`Writing ${DIAGNOSTIC_FILE}: ${err}`);
|
|
333740
|
+
else
|
|
333741
|
+
resolve();
|
|
333742
|
+
});
|
|
333743
|
+
});
|
|
333744
|
+
}
|
|
333745
|
+
|
|
333465
333746
|
;// CONCATENATED MODULE: ../operator/src/signals.ts
|
|
333466
333747
|
|
|
333467
333748
|
function initSignalsHandler(Mapper) {
|
|
@@ -333484,6 +333765,7 @@ function initSignalsHandler(Mapper) {
|
|
|
333484
333765
|
|
|
333485
333766
|
|
|
333486
333767
|
|
|
333768
|
+
|
|
333487
333769
|
/*
|
|
333488
333770
|
* Dead-Letter Handler
|
|
333489
333771
|
*
|
|
@@ -333495,6 +333777,7 @@ async function deadLetterHandler(workItem) {
|
|
|
333495
333777
|
const itemPath = workItem.handler.itemPath();
|
|
333496
333778
|
workItem.workStatus = WorkStatus.FINISHED;
|
|
333497
333779
|
workItem.isDeadLetter = true;
|
|
333780
|
+
incrementDiagnosticErrorCount();
|
|
333498
333781
|
// we try to put the CR in a correct state
|
|
333499
333782
|
try {
|
|
333500
333783
|
await updateTransition(itemPath, operation, 'ERROR', 'True', 'Uncontrolled error (DLH)');
|
|
@@ -333639,7 +333922,7 @@ class CRStateMetrics {
|
|
|
333639
333922
|
this.onUpdate = false;
|
|
333640
333923
|
}
|
|
333641
333924
|
async __prepareConnection() {
|
|
333642
|
-
const { kc, opts } = await
|
|
333925
|
+
const { kc, opts } = await connection_getConnection();
|
|
333643
333926
|
const k8sApi = kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
333644
333927
|
this.fListCRs = async () => {
|
|
333645
333928
|
try {
|
|
@@ -333783,6 +334066,7 @@ ProcessorGlobalMetrics._instance = null;
|
|
|
333783
334066
|
|
|
333784
334067
|
|
|
333785
334068
|
|
|
334069
|
+
|
|
333786
334070
|
let processMetricsSlotProvider = null;
|
|
333787
334071
|
/* harmony default export */ async function metricsServer(kindList, namespace) {
|
|
333788
334072
|
const portFromEnv = process.env.METRICS_PORT;
|
|
@@ -333801,6 +334085,7 @@ async function startMetrics(exporter, attributes, kindList, namespace) {
|
|
|
333801
334085
|
});
|
|
333802
334086
|
const meter = meterProvider.getMeter('firestartr');
|
|
333803
334087
|
void startQueueMetrics(meter, attributes);
|
|
334088
|
+
void startApiCallMetrics(meter, attributes);
|
|
333804
334089
|
void startMemoryMetrics(meter, attributes);
|
|
333805
334090
|
void startCRStates(meter, kindList, namespace);
|
|
333806
334091
|
processMetricsSlotProvider = (slotId) => {
|
|
@@ -333862,6 +334147,14 @@ async function startQueueMetrics(meter, attributes) {
|
|
|
333862
334147
|
nDeferred = queueMetrics.nItemsDeferred || 0;
|
|
333863
334148
|
}, 1000);
|
|
333864
334149
|
}
|
|
334150
|
+
async function startApiCallMetrics(meter, attributes) {
|
|
334151
|
+
const concurrentGauge = meter.createObservableGauge('firestartr_api_calls_concurrent', { description: 'Current number of in-flight Kubernetes API read calls' });
|
|
334152
|
+
const awaitingGauge = meter.createObservableGauge('firestartr_api_calls_awaiting', {
|
|
334153
|
+
description: 'Current number of Kubernetes API read calls waiting for a slot',
|
|
334154
|
+
});
|
|
334155
|
+
concurrentGauge.addCallback((observer) => observer.observe(getCurrentConcurrentApiCalls(), attributes));
|
|
334156
|
+
awaitingGauge.addCallback((observer) => observer.observe(getPendingApiCalls(), attributes));
|
|
334157
|
+
}
|
|
333865
334158
|
async function startMemoryMetrics(meter, attributes) {
|
|
333866
334159
|
const usedMemoryCounter = meter.createObservableGauge('firestartr_used_memory', { description: 'Used memory in bytes' });
|
|
333867
334160
|
let heapUsage = process.memoryUsage().heapUsed;
|
|
@@ -334010,7 +334303,15 @@ class ProcessItemSlot {
|
|
|
334010
334303
|
async __run(workItem) {
|
|
334011
334304
|
if (!workItem.getItem || !workItem.process || !workItem.operation)
|
|
334012
334305
|
return;
|
|
334306
|
+
const raceDelayMs = process.env.RACE_DELAY_MS
|
|
334307
|
+
? Number.parseInt(process.env.RACE_DELAY_MS, 10)
|
|
334308
|
+
: 0;
|
|
334309
|
+
if (raceDelayMs > 0) {
|
|
334310
|
+
const jitter = Math.floor(Math.random() * raceDelayMs);
|
|
334311
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
334312
|
+
}
|
|
334013
334313
|
const item = await workItem.getItem();
|
|
334314
|
+
workItem.item = item;
|
|
334014
334315
|
// we check if the workItem needs blocking
|
|
334015
334316
|
// if it does need it we return because we cannot
|
|
334016
334317
|
// process this item
|
|
@@ -334231,6 +334532,7 @@ function sortQueue(queue) {
|
|
|
334231
334532
|
|
|
334232
334533
|
|
|
334233
334534
|
|
|
334535
|
+
|
|
334234
334536
|
const queue = [];
|
|
334235
334537
|
let _deferredBookkeeper = null;
|
|
334236
334538
|
let _activeParentKeys = new Set();
|
|
@@ -334340,6 +334642,7 @@ async function processItem(workItem) {
|
|
|
334340
334642
|
*/
|
|
334341
334643
|
async function processItem_loop() {
|
|
334342
334644
|
loopWorkItemDebug(queue);
|
|
334645
|
+
loopDiagnosticFile(queue, MAX_SLOTS);
|
|
334343
334646
|
const deferredBookkeeper = new DeferredSchedulingBookkeeper();
|
|
334344
334647
|
_deferredBookkeeper = deferredBookkeeper;
|
|
334345
334648
|
const processItemSlotsManager = initProcessItemsSlots(MAX_SLOTS, true, (w) => deferredBookkeeper.incrementBlockedAttempt(w));
|
|
@@ -337804,7 +338107,7 @@ var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_);
|
|
|
337804
338107
|
|
|
337805
338108
|
|
|
337806
338109
|
async function getCurrentPod(namespace = 'default') {
|
|
337807
|
-
const { kc } = await
|
|
338110
|
+
const { kc } = await connection_getConnection();
|
|
337808
338111
|
const k8sApi = kc.makeApiClient(client_node_dist.CoreV1Api);
|
|
337809
338112
|
const podName = (0,external_os_.hostname)();
|
|
337810
338113
|
const pod = await k8sApi.readNamespacedPod(podName, namespace);
|
|
@@ -337826,7 +338129,7 @@ class LeaseAcquisitionError extends Error {
|
|
|
337826
338129
|
* automatically after 30 seconds.
|
|
337827
338130
|
*/
|
|
337828
338131
|
async function tryAcquireOrRenewLease(namespace, leaseDurationSeconds) {
|
|
337829
|
-
const { kc } = await
|
|
338132
|
+
const { kc } = await connection_getConnection();
|
|
337830
338133
|
const k8sApi = kc.makeApiClient(client_node_dist.CoordinationV1Api);
|
|
337831
338134
|
const name = 'firestartr-lease';
|
|
337832
338135
|
const currentPod = await getCurrentPod(namespace);
|
|
@@ -338405,7 +338708,7 @@ class Ctx {
|
|
|
338405
338708
|
|
|
338406
338709
|
|
|
338407
338710
|
async function getTFWorkspaceRefs(_claimKind, claimName, namespace) {
|
|
338408
|
-
const { kc, opts } = await
|
|
338711
|
+
const { kc, opts } = await connection_getConnection();
|
|
338409
338712
|
await kc.makeApiClient(client_node_dist.CustomObjectsApi);
|
|
338410
338713
|
const normalizedClaimName = catalog_common/* default.generic.normalizeLabel */.Z.generic.normalizeLabel(claimName);
|
|
338411
338714
|
console.log('💡', normalizedClaimName);
|
|
@@ -338659,8 +338962,8 @@ const MODULES = {
|
|
|
338659
338962
|
},
|
|
338660
338963
|
FirestartrGithubOrganizationSettings: {
|
|
338661
338964
|
module: 'git::https://github.com/prefapp/tfm.git//modules/github-org-settings',
|
|
338662
|
-
//
|
|
338663
|
-
ref: '
|
|
338965
|
+
// org settings module merged to main (prefapp/tfm#1253)
|
|
338966
|
+
ref: 'cf2e2ae487b6cc3f7b208f46a92f5b5f97f8fef2',
|
|
338664
338967
|
},
|
|
338665
338968
|
};
|
|
338666
338969
|
function getFirestartrDefaultTFM(kind) {
|
|
@@ -339777,11 +340080,14 @@ async function provisionManagedFiles(ghFeature) {
|
|
|
339777
340080
|
// the repo if available so the seed commit preserves the current state.
|
|
339778
340081
|
newlyProvisionedAddresses.push(address);
|
|
339779
340082
|
try {
|
|
339780
|
-
const content = await ghFeature.getFileContentFromProvider(cr.spec.org,
|
|
340083
|
+
const content = await ghFeature.getFileContentFromProvider(cr.spec.org, repoRef.getDepName(), branch, file.path);
|
|
339781
340084
|
file.content = Buffer.from(content, 'binary').toString('base64');
|
|
339782
340085
|
}
|
|
339783
340086
|
catch (e) {
|
|
339784
|
-
|
|
340087
|
+
if (e?.status !== 404) {
|
|
340088
|
+
throw e;
|
|
340089
|
+
}
|
|
340090
|
+
gh_provisioner_src_logger.info(`File ${file.path} not found in repo ${repoInfo.ref?.name} on branch ${branch}. Using declared content`);
|
|
339785
340091
|
}
|
|
339786
340092
|
createFileProvision(ghFeature, file);
|
|
339787
340093
|
}
|
|
@@ -339965,6 +340271,7 @@ async function endDebug(entity) {
|
|
|
339965
340271
|
|
|
339966
340272
|
|
|
339967
340273
|
const tp_bridge_TF_PROJECTS_PATH = '/tmp/gh-workspaces';
|
|
340274
|
+
const KUBERNETES_LABEL_VALUE_MAX_LENGTH = 63;
|
|
339968
340275
|
async function runOnTerraform(entity, command, customArgs, opts = {}) {
|
|
339969
340276
|
if (!entity || typeof entity !== 'object')
|
|
339970
340277
|
throw new Error('[BUG] entity is invalid in runOnTerraform');
|
|
@@ -340054,11 +340361,27 @@ function calculateTFStatePath(entity, backend) {
|
|
|
340054
340361
|
tfStatePath = `grss/${entity.cr.spec.firestartr.tfStateKey}`.substring(0, 63);
|
|
340055
340362
|
}
|
|
340056
340363
|
else {
|
|
340057
|
-
|
|
340364
|
+
const kind = entity.cr.kind.toLowerCase();
|
|
340365
|
+
const tfStateKey = entity.cr.spec.firestartr.tfStateKey;
|
|
340366
|
+
tfStatePath = `${kind}/${tfStateKey}`;
|
|
340367
|
+
if ('kubernetes' in backend) {
|
|
340368
|
+
tfStatePath = fitKubernetesBackendLabel(tfStatePath, kind, tfStateKey);
|
|
340369
|
+
}
|
|
340058
340370
|
}
|
|
340059
340371
|
gh_provisioner_src_logger.debug(`[gh-provisioner] tfStateKey for ${entity.k8sId} = '${tfStatePath}'`);
|
|
340060
340372
|
return tfStatePath;
|
|
340061
340373
|
}
|
|
340374
|
+
function fitKubernetesBackendLabel(tfStatePath, kind, tfStateKey) {
|
|
340375
|
+
if (tfStatePath.split('/').join('-').length <= KUBERNETES_LABEL_VALUE_MAX_LENGTH) {
|
|
340376
|
+
return tfStatePath;
|
|
340377
|
+
}
|
|
340378
|
+
const tfStateKeyLabelLength = tfStateKey.split('/').join('-').length;
|
|
340379
|
+
const maxKindLength = KUBERNETES_LABEL_VALUE_MAX_LENGTH - tfStateKeyLabelLength - 1;
|
|
340380
|
+
if (maxKindLength < 1) {
|
|
340381
|
+
return tfStateKey.substring(0, KUBERNETES_LABEL_VALUE_MAX_LENGTH);
|
|
340382
|
+
}
|
|
340383
|
+
return `${kind.substring(0, maxKindLength)}/${tfStateKey}`;
|
|
340384
|
+
}
|
|
340062
340385
|
|
|
340063
340386
|
;// CONCATENATED MODULE: ../gh_provisioner/src/entities/ghfeature/index.ts
|
|
340064
340387
|
|
|
@@ -340219,15 +340542,9 @@ class EntityGHFeature extends base_Entity {
|
|
|
340219
340542
|
throw new Error(`[gh-provisioner] ${this.k8sId} on untracking files: ${err}`);
|
|
340220
340543
|
}
|
|
340221
340544
|
}
|
|
340222
|
-
async getFileContentFromProvider(org,
|
|
340223
|
-
const
|
|
340224
|
-
|
|
340225
|
-
const response = await octokit.request(`GET ${url}`, {
|
|
340226
|
-
baseUrl: 'https://raw.githubusercontent.com',
|
|
340227
|
-
});
|
|
340228
|
-
return response.data;
|
|
340229
|
-
});
|
|
340230
|
-
return v;
|
|
340545
|
+
async getFileContentFromProvider(org, repo, branch, path) {
|
|
340546
|
+
const content = await this.runWithGithubProvider(() => github["default"].repo.getContent(path, repo, org, branch));
|
|
340547
|
+
return content;
|
|
340231
340548
|
}
|
|
340232
340549
|
}
|
|
340233
340550
|
function parseStateList(output) {
|
|
@@ -342173,6 +342490,7 @@ function isObserveModeActive() {
|
|
|
342173
342490
|
// (warmup and legacy provisioner code replaced by TFM mirror system)
|
|
342174
342491
|
function runOperator(opts) {
|
|
342175
342492
|
const { ignoreLease, dummyExec, namespace, kindList, importMode, importModeSkipPlan, observeMode, withMetrics, } = opts;
|
|
342493
|
+
const implementedKinds = filterImplementedKinds(kindList);
|
|
342176
342494
|
if (observeMode)
|
|
342177
342495
|
observeModeActive = true;
|
|
342178
342496
|
if (withMetrics)
|
|
@@ -342206,7 +342524,7 @@ function runOperator(opts) {
|
|
|
342206
342524
|
await leasePromise;
|
|
342207
342525
|
};
|
|
342208
342526
|
if (withMetricsMode) {
|
|
342209
|
-
void metricsServer(
|
|
342527
|
+
void metricsServer(implementedKinds, namespace);
|
|
342210
342528
|
}
|
|
342211
342529
|
void (async () => {
|
|
342212
342530
|
await run(namespace, () => {
|
|
@@ -342214,7 +342532,7 @@ function runOperator(opts) {
|
|
|
342214
342532
|
void observeKind('githubgroups', namespace, processItem, dummy);
|
|
342215
342533
|
}
|
|
342216
342534
|
else {
|
|
342217
|
-
for (const kind of
|
|
342535
|
+
for (const kind of implementedKinds) {
|
|
342218
342536
|
observeKind(kind, namespace, processItem, getProvisionImplementation(kind))
|
|
342219
342537
|
.then((res) => {
|
|
342220
342538
|
console.log('exit kind', kind);
|
|
@@ -342236,30 +342554,31 @@ function runOperator(opts) {
|
|
|
342236
342554
|
});
|
|
342237
342555
|
})();
|
|
342238
342556
|
}
|
|
342557
|
+
const provisionImplementations = {
|
|
342558
|
+
terraformworkspaces: processOperation,
|
|
342559
|
+
terraformworkspaceplans: processOperationPlan,
|
|
342560
|
+
githubgroups: process_operation_processOperation,
|
|
342561
|
+
githubrepositories: process_operation_processOperation,
|
|
342562
|
+
githubrepositorysecretssections: process_operation_processOperation,
|
|
342563
|
+
githubrepositoryfeatures: process_operation_processOperation,
|
|
342564
|
+
githubmemberships: process_operation_processOperation,
|
|
342565
|
+
githuborgwebhooks: process_operation_processOperation,
|
|
342566
|
+
githuborganizationsettings: process_operation_processOperation,
|
|
342567
|
+
fsdummiesa: processFirestartrDummies,
|
|
342568
|
+
fsdummiesb: processFirestartrDummies,
|
|
342569
|
+
fsdummiesc: processFirestartrDummies,
|
|
342570
|
+
};
|
|
342571
|
+
function filterImplementedKinds(kindList) {
|
|
342572
|
+
return kindList.filter((kind) => {
|
|
342573
|
+
if (Object.prototype.hasOwnProperty.call(provisionImplementations, kind)) {
|
|
342574
|
+
return true;
|
|
342575
|
+
}
|
|
342576
|
+
operator_src_logger.warn(`Ignoring configured kind '${kind}': no implementation found`);
|
|
342577
|
+
return false;
|
|
342578
|
+
});
|
|
342579
|
+
}
|
|
342239
342580
|
function getProvisionImplementation(plural) {
|
|
342240
|
-
|
|
342241
|
-
switch (plural) {
|
|
342242
|
-
case 'terraformworkspaces':
|
|
342243
|
-
implementation = processOperation;
|
|
342244
|
-
break;
|
|
342245
|
-
case 'terraformworkspaceplans':
|
|
342246
|
-
implementation = processOperationPlan;
|
|
342247
|
-
break;
|
|
342248
|
-
case 'githubgroups':
|
|
342249
|
-
case 'githubrepositories':
|
|
342250
|
-
case 'githubrepositorysecretssections':
|
|
342251
|
-
case 'githubrepositoryfeatures':
|
|
342252
|
-
case 'githubmemberships':
|
|
342253
|
-
case 'githuborgwebhooks':
|
|
342254
|
-
case 'githuborganizationsettings':
|
|
342255
|
-
implementation = process_operation_processOperation;
|
|
342256
|
-
break;
|
|
342257
|
-
case 'fsdummiesa':
|
|
342258
|
-
case 'fsdummiesb':
|
|
342259
|
-
case 'fsdummiesc':
|
|
342260
|
-
implementation = processFirestartrDummies;
|
|
342261
|
-
break;
|
|
342262
|
-
}
|
|
342581
|
+
const implementation = provisionImplementations[plural];
|
|
342263
342582
|
if (!implementation)
|
|
342264
342583
|
throw new Error(`No implementation found for ${plural}`);
|
|
342265
342584
|
operator_src_logger.info(`Retrieved the provision implementation for the kind '${plural}'`);
|
|
@@ -521050,7 +521369,7 @@ const crsStatusSubcommand = {
|
|
|
521050
521369
|
};
|
|
521051
521370
|
|
|
521052
521371
|
;// CONCATENATED MODULE: ./package.json
|
|
521053
|
-
const package_namespaceObject = JSON.parse('{"i8":"2.7.0-snapshot-
|
|
521372
|
+
const package_namespaceObject = JSON.parse('{"i8":"2.7.0-snapshot-22"}');
|
|
521054
521373
|
;// CONCATENATED MODULE: ../../package.json
|
|
521055
521374
|
const package_namespaceObject_1 = {"i8":"2.7.0"};
|
|
521056
521375
|
;// CONCATENATED MODULE: ./src/subcommands/index.ts
|
|
@@ -35,5 +35,5 @@ export declare class EntityGHFeature extends Entity {
|
|
|
35
35
|
* provisioned with old or new code.
|
|
36
36
|
*/
|
|
37
37
|
keepUntrackedFiles(_tfOp: string): Promise<void>;
|
|
38
|
-
getFileContentFromProvider(org: string,
|
|
38
|
+
getFileContentFromProvider(org: string, repo: string, branch: string, path: string): Promise<string>;
|
|
39
39
|
}
|
|
@@ -5,3 +5,4 @@ export declare function isImportMode(): boolean;
|
|
|
5
5
|
export declare function isImportModeSkipPlan(): boolean;
|
|
6
6
|
export declare function isObserveModeActive(): boolean;
|
|
7
7
|
export declare function runOperator(opts: any): void;
|
|
8
|
+
export declare function filterImplementedKinds(kindList: string[]): string[];
|
|
@@ -13,10 +13,8 @@ export declare function writeStatus(kind: string, namespace: string, item: any):
|
|
|
13
13
|
export declare function writeFinalizer(kind: string, namespace: string, item: any): Promise<any>;
|
|
14
14
|
export declare function listItems(kind: string, namespace: string, kc: any, opts: any): Promise<Array<any>>;
|
|
15
15
|
export declare function observeList(kind: string, namespace: string, revision: string, kc: any, opts: any): AsyncGenerator<any, void, unknown>;
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
opts: any;
|
|
19
|
-
}>;
|
|
16
|
+
export { getConnection } from './connection';
|
|
17
|
+
export { getCurrentConcurrentApiCalls, getPendingApiCalls, getPeakConcurrentApiCalls, } from './utils/api-read-limiter';
|
|
20
18
|
export declare function upsertResult(namespace: string, item: any, result: string, exitCode?: number, existingRetryCount?: number): Promise<any>;
|
|
21
19
|
export declare function deleteSecret(secretName: string, namespace: string): Promise<any>;
|
|
22
20
|
export declare function upsertSecret(namespace: string, secret: any): Promise<void>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Semaphore } from './semaphore';
|
|
2
|
+
export declare function computeMaxConcurrentApiCalls(rawMaxConcurrent: string | undefined, rawMaxSlots: string | undefined): number;
|
|
3
|
+
export declare const apiReadSemaphore: Semaphore;
|
|
4
|
+
export declare function withApiReadSlot<T>(read: () => Promise<T>): Promise<T>;
|
|
5
|
+
export declare function getPeakConcurrentApiCalls(): number;
|
|
6
|
+
export declare function getCurrentConcurrentApiCalls(): number;
|
|
7
|
+
export declare function getPendingApiCalls(): number;
|
|
8
|
+
export declare function getMaxConcurrentApiCalls(): number;
|
|
9
|
+
export declare function getTotalApiAcquisitions(): number;
|
|
10
|
+
export declare function getTimesSemaphoreSaturated(): number;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class Semaphore {
|
|
2
|
+
private readonly _max;
|
|
3
|
+
private _current;
|
|
4
|
+
private readonly _queue;
|
|
5
|
+
private _totalAcquisitions;
|
|
6
|
+
private _timesSaturated;
|
|
7
|
+
constructor(max: number);
|
|
8
|
+
get max(): number;
|
|
9
|
+
get current(): number;
|
|
10
|
+
get waiting(): number;
|
|
11
|
+
get totalAcquisitions(): number;
|
|
12
|
+
get timesSaturated(): number;
|
|
13
|
+
acquire(): Promise<void>;
|
|
14
|
+
release(): void;
|
|
15
|
+
}
|