@firestartr/cli 1.54.0 → 1.55.0-snapshot-1

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 CHANGED
@@ -355878,7 +355878,7 @@ function createCodeOwnersData(claim, additionalRules) {
355878
355878
  message = concatLine(message, `\n${paddedAsterisk}${resolveCodeownersRef(claim.owner, claim.providers.github.org)}`);
355879
355879
  }
355880
355880
  if (claim.platformOwner) {
355881
- message = concatLine(message, `\n${paddedAsterisk}${resolveCodeownersRef(claim.platformOwner, claim.providers.github.org)}`);
355881
+ message = concatLine(message, `\n${'/.github/'.padEnd(25)}${resolveCodeownersRef(claim.platformOwner, claim.providers.github.org)}`);
355882
355882
  }
355883
355883
  if (additionalRules) {
355884
355884
  for (const rule of additionalRules) {
@@ -357903,7 +357903,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
357903
357903
  },
357904
357904
  owner: {
357905
357905
  type: 'string',
357906
- pattern: '^(user|group):[a-zA-Z0-9_-]+$',
357906
+ pattern: '^(user|group):.+$',
357907
357907
  },
357908
357908
  },
357909
357909
  required: ['description', 'owner'],
@@ -359664,6 +359664,13 @@ var ajv_default = /*#__PURE__*/__nccwpck_require__.n(dist_ajv);
359664
359664
  },
359665
359665
  },
359666
359666
  },
359667
+ filesTemplates: {
359668
+ type: 'array',
359669
+ description: 'a list of references to a different file where files key is filled by an expanded template',
359670
+ items: {
359671
+ type: 'string',
359672
+ },
359673
+ },
359667
359674
  },
359668
359675
  required: ['args', 'feature_name', 'files', 'patches'],
359669
359676
  title: 'root',
@@ -359683,7 +359690,7 @@ var ajv_default = /*#__PURE__*/__nccwpck_require__.n(dist_ajv);
359683
359690
  additionalProperties: false,
359684
359691
  properties: {
359685
359692
  $lit: {
359686
- type: 'string',
359693
+ type: ['string', 'boolean'],
359687
359694
  },
359688
359695
  $ref: {
359689
359696
  type: 'array',
@@ -359694,8 +359701,11 @@ var ajv_default = /*#__PURE__*/__nccwpck_require__.n(dist_ajv);
359694
359701
  $arg: {
359695
359702
  type: 'string',
359696
359703
  },
359704
+ $template: {
359705
+ type: 'string',
359706
+ },
359697
359707
  $default: {
359698
- type: ['string', 'array'],
359708
+ type: ['string', 'array', 'boolean'],
359699
359709
  },
359700
359710
  },
359701
359711
  },
@@ -359775,7 +359785,9 @@ function __validateFeatureConfig(featurePath) {
359775
359785
  }
359776
359786
  }
359777
359787
  function __validateFeatureConfigData(configData) {
359778
- const ajv = new (ajv_default())();
359788
+ const ajv = new (ajv_default())({
359789
+ allowUnionTypes: true,
359790
+ });
359779
359791
  const validate = ajv.compile(src_schema);
359780
359792
  const valid = validate(configData);
359781
359793
  if (!valid) {
@@ -360609,10 +360621,14 @@ function addTraceabilityStamp(context, content) {
360609
360621
 
360610
360622
 
360611
360623
 
360624
+
360612
360625
  function render(featurePath, featureRenderPath, entity, firestartrConfig = {}, featureArgs = {}) {
360613
360626
  const configData = validate_validate(featurePath);
360614
360627
  const context = buildContext(entity, configData.args, firestartrConfig, featureArgs);
360615
360628
  context.config = JSON.parse(renderContent(JSON.stringify(configData), context));
360629
+ if ('filesTemplates' in context.config) {
360630
+ expandFiles(featurePath, configData, context);
360631
+ }
360616
360632
  const output = { files: [] };
360617
360633
  context.config.files.forEach((file) => {
360618
360634
  const { src, dest } = file;
@@ -360668,8 +360684,50 @@ function buildContext(entity, args, firestartrConfig, featureArgs) {
360668
360684
  });
360669
360685
  context.firestartrConfig = firestartrConfig;
360670
360686
  context.traceability = featureArgs['traceability'] || {};
360687
+ buildTemplateArgs(args, context);
360671
360688
  return context;
360672
360689
  }
360690
+ /**
360691
+ * Mutates the provided context object by adding properties for each argument
360692
+ * that has a `$template`, using the current context to render the template content.
360693
+ *
360694
+ * @param args - Argument definitions, where each entry may contain a `$template` key.
360695
+ * @param context - The context object to be mutated with rendered template values.
360696
+ * @returns void
360697
+ */
360698
+ function buildTemplateArgs(args, context) {
360699
+ Object.entries(args).forEach(([key, arg]) => {
360700
+ if ('$template' in arg) {
360701
+ context[key] = renderContent(arg['$template'], context);
360702
+ }
360703
+ });
360704
+ }
360705
+ function expandFiles(featurePath, configData, context) {
360706
+ let files = [];
360707
+ for (const tpl of configData.filesTemplates) {
360708
+ const addToFiles = expandFilesTemplate(featurePath, tpl, context);
360709
+ files = files.concat(addToFiles).flat(Infinity);
360710
+ }
360711
+ context.config.files = context.config.files.concat(files).flat(Infinity);
360712
+ }
360713
+ function expandFilesTemplate(featurePath, tplPath, context) {
360714
+ const templatePath = external_path_default().join(featurePath, tplPath);
360715
+ features_renderer_src_logger.debug(`Expanding files section with template located at ${templatePath}`);
360716
+ let template;
360717
+ try {
360718
+ template = external_fs_default().readFileSync(templatePath).toString();
360719
+ }
360720
+ catch (err) {
360721
+ const message = err && err.message ? err.message : String(err);
360722
+ features_renderer_src_logger.error(`Failed to read template file at "${templatePath}": ${message}`);
360723
+ throw new Error(`Failed to read template file at "${templatePath}": ${message}`);
360724
+ }
360725
+ const renderedTemplate = renderContent(template, context);
360726
+ const data = catalog_common.io.fromYaml(renderedTemplate) || { files: [] };
360727
+ if (!data.files)
360728
+ data.files = [];
360729
+ return data.files.filter((file) => file);
360730
+ }
360673
360731
  function renderContent(template, ctx) {
360674
360732
  return mustache_mustache.render(template, ctx, {}, ['{{|', '|}}']);
360675
360733
  }
@@ -360739,7 +360797,7 @@ function loadAndValidateRenderTests(featurePath) {
360739
360797
  throw new Error(`render_tests.yaml is required but not found at ${file}`);
360740
360798
  }
360741
360799
  const raw = loadYaml(file);
360742
- const ajv = new (ajv_default())({ allErrors: true, strict: true });
360800
+ const ajv = new (ajv_default())({ allErrors: true, strict: true, allowUnionTypes: true });
360743
360801
  const validate = ajv.compile(renderTestsSchema);
360744
360802
  const ok = validate(raw);
360745
360803
  if (!ok) {
@@ -367680,12 +367738,28 @@ async function addDestroyCommitStatus(cr, state, description = '', context = '')
367680
367738
  async function addPlanStatusCheck(prUrl, summary, status = 'in_progress', isFailure = false) {
367681
367739
  try {
367682
367740
  operator_src_logger.debug(`The ctl is checking the length of the plan summary, which is '${summary.length}'.`);
367683
- if (summary.length > MAX_CHARS_OUPUT_PLAN) {
367741
+ // Determine if we should wrap in fences
367742
+ const shouldWrap = status === 'completed' && !summary.includes('```');
367743
+ const FENCE_OVERHEAD = 17; // "```terraform\n" + "\n```"
367744
+ let processedSummary = summary;
367745
+ if (shouldWrap) {
367746
+ // Truncate accounting for fence overhead
367747
+ const maxBodyLength = MAX_CHARS_OUPUT_PLAN - FENCE_OVERHEAD;
367748
+ if (summary.length > maxBodyLength) {
367749
+ const mustDrop = summary.length - maxBodyLength;
367750
+ processedSummary = summary.substring(mustDrop);
367751
+ operator_src_logger.debug(`The ctl found the plan summary too lengthy (length: '${summary.length}'). The summary must drop because '${mustDrop}'.`);
367752
+ }
367753
+ // Wrap in fences
367754
+ processedSummary = `\`\`\`terraform\n${processedSummary}\n\`\`\``;
367755
+ }
367756
+ else if (summary.length > MAX_CHARS_OUPUT_PLAN) {
367757
+ // Truncate without wrapping
367684
367758
  const mustDrop = summary.length - MAX_CHARS_OUPUT_PLAN;
367685
- summary = summary.substring(mustDrop);
367759
+ processedSummary = summary.substring(mustDrop);
367686
367760
  operator_src_logger.debug(`The ctl found the plan summary too lengthy (length: '${summary.length}'). The summary must drop because '${mustDrop}'.`);
367687
367761
  }
367688
- await ctl_addStatusCheck({ summary, title: 'Terraform Plan Results' }, isFailure, 'terraform_plan', prUrl, status);
367762
+ await ctl_addStatusCheck({ summary: processedSummary, title: 'Terraform Plan Results' }, isFailure, 'terraform_plan', prUrl, status);
367689
367763
  }
367690
367764
  catch (e) {
367691
367765
  operator_src_logger.error(`The ctl encountered an error while adding plan status for PR '${prUrl}' with status '${status}'. Is Failure: '${isFailure}'. Error: '${e}'.`);
@@ -367825,29 +367899,91 @@ async function observe(plural, namespace, onAdd, onChange, onDelete, _onRename)
367825
367899
  }
367826
367900
  }
367827
367901
 
367902
+ ;// CONCATENATED MODULE: ../operator/src/high_priority_status.ts
367903
+
367904
+ const SORTED_PRIORITIES = [
367905
+ 'PROVISIONING',
367906
+ 'ERROR',
367907
+ 'OUT_OF_SYNC',
367908
+ 'PLANNING',
367909
+ 'DELETING',
367910
+ 'SYNCHRONIZED',
367911
+ 'PROVISIONED',
367912
+ 'DELETED',
367913
+ ];
367914
+ function setHighPriorityStatus(item) {
367915
+ const highPriorityCondition = conditionsSorter(item.status?.conditions || []);
367916
+ let highPriorityState = null;
367917
+ if (highPriorityCondition) {
367918
+ highPriorityState = {
367919
+ type: highPriorityCondition.type,
367920
+ reason: highPriorityCondition.reason,
367921
+ };
367922
+ }
367923
+ else {
367924
+ highPriorityState = {
367925
+ type: 'UNKNOWN',
367926
+ reason: 'AwaitingReconciliation',
367927
+ };
367928
+ }
367929
+ item.status.highPriorityState = highPriorityState.type;
367930
+ item.status.highPriorityReason = highPriorityState.reason;
367931
+ operator_src_logger.silly(`${item.kind}/${item.metadata.name} - Set HighPriorityStatus to ${item.status.highPriorityState} - ${item.status.highPriorityReason}`);
367932
+ }
367933
+ function conditionsSorter(conditions) {
367934
+ if (conditions.length === 0)
367935
+ return null;
367936
+ const getPriority = (type) => {
367937
+ const index = SORTED_PRIORITIES.indexOf(type);
367938
+ return index === -1 ? Number.MAX_SAFE_INTEGER : index;
367939
+ };
367940
+ return conditions
367941
+ .filter((condition) => {
367942
+ return condition.status === 'True';
367943
+ })
367944
+ .sort((a, b) => {
367945
+ const priorityA = getPriority(a.type);
367946
+ const priorityB = getPriority(b.type);
367947
+ return priorityA - priorityB;
367948
+ })[0];
367949
+ }
367950
+
367828
367951
  ;// CONCATENATED MODULE: ../operator/src/status.ts
367829
367952
 
367830
367953
 
367831
- async function needsProvisioningOnCreate(cr) {
367954
+
367955
+ async function upsertInitialStatus(pluralKind, namespace, item) {
367956
+ item = await getItemByItemPath(`${namespace}/${pluralKind}/${item.metadata.name}`);
367957
+ if (!('status' in item))
367958
+ item.status = {};
367959
+ if (!('conditions' in item.status))
367960
+ item.status.conditions = [];
367961
+ await writePrioritizedStatus(pluralKind, namespace, item);
367962
+ }
367963
+ async function needsProvisioningOnCreateOrUpdate(cr) {
367832
367964
  const fCrLog = (cr) => `The item ${cr.kind}: ${cr.metadata.name}`;
367833
367965
  // NO STATUS
367834
367966
  if (!('status' in cr) || !('conditions' in cr.status)) {
367835
367967
  operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is missing a status and any conditions.`);
367836
- return true;
367968
+ return { needs: true, reason: 'CREATED' };
367837
367969
  }
367838
367970
  // ERROR
367839
367971
  const errCond = getConditionByType(cr.status.conditions, 'ERROR');
367840
367972
  if (errCond && errCond.status === 'True') {
367841
367973
  operator_src_logger.debug(`Skipping the provisioning process for custom resource '${cr.kind}/${cr.metadata.name}' due to a status error.`);
367842
- return false;
367974
+ return { needs: false };
367843
367975
  }
367844
367976
  // PROVISIONED
367845
367977
  const provCond = getConditionByType(cr.status.conditions, 'PROVISIONED');
367846
- if (provCond &&
367847
- provCond.status === 'True' &&
367848
- provCond.observedGeneration >= cr.metadata.generation) {
367849
- operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is already provisioned; skipping the process.`);
367850
- return false;
367978
+ if (provCond && provCond.status === 'True') {
367979
+ if (provCond.observedGeneration >= cr.metadata.generation) {
367980
+ operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is already provisioned; skipping the process.`);
367981
+ return { needs: false };
367982
+ }
367983
+ else {
367984
+ operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is already provisioned but it has spec changes not observed; handling.`);
367985
+ return { needs: true, reason: 'UPDATED' };
367986
+ }
367851
367987
  }
367852
367988
  // DELETED
367853
367989
  const delCond = getConditionByType(cr.status.conditions, 'DELETED');
@@ -367855,16 +367991,16 @@ async function needsProvisioningOnCreate(cr) {
367855
367991
  delCond.status === 'True' &&
367856
367992
  delCond.observedGeneration >= cr.metadata.generation) {
367857
367993
  operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' has already been deleted; no action is required.`);
367858
- return false;
367994
+ return { needs: false };
367859
367995
  }
367860
367996
  // PROVISIONING
367861
367997
  const provisioningCondition = getConditionByType(cr.status.conditions, 'PROVISIONING');
367862
367998
  if (provisioningCondition && provisioningCondition.status === 'True') {
367863
367999
  operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is currently in a provisioning or reprovisioning state.`);
367864
- return true;
368000
+ return { needs: true, reason: 'UPDATED' };
367865
368001
  }
367866
368002
  operator_src_logger.debug(`Skipping the provisioning process for custom resource '${cr.kind}/${cr.metadata.name}' because its current state is not handled.`);
367867
- return false;
368003
+ return { needs: false };
367868
368004
  }
367869
368005
  async function updateSyncTransition(itemPath, reason, lastSyncTime, nextSyncTime, message, status) {
367870
368006
  operator_src_logger.info(`The item at '${itemPath}' transitioned to a new SYNCHRONIZED condition of '${status}'. The reason for the change is '${reason}' with the message: '${message}'.`);
@@ -367886,7 +368022,11 @@ async function updateSyncTransition(itemPath, reason, lastSyncTime, nextSyncTime
367886
368022
  };
367887
368023
  k8sItem.status.conditions = updateConditionByType(k8sItem.status.conditions, 'SYNCHRONIZED', conditionObject);
367888
368024
  const itemParameters = itemPath.split('/');
367889
- await writeStatus(itemParameters[1], itemParameters[0], k8sItem);
368025
+ await writePrioritizedStatus(itemParameters[1], itemParameters[0], k8sItem);
368026
+ }
368027
+ async function writePrioritizedStatus(kind, namespace, item) {
368028
+ setHighPriorityStatus(item);
368029
+ await writeStatus(kind, namespace, item);
367890
368030
  }
367891
368031
  async function updateTransition(itemPath, reason, type, statusValue, message = '', updateStatusOnly = false) {
367892
368032
  operator_src_logger.info(`The item at '${itemPath}' transitioned to a new status of '${statusValue}' (type: '${type}'). The reason for the change is '${reason}' with the message: '${message}'. This was a status-only update: '${updateStatusOnly}'.`);
@@ -367904,7 +368044,7 @@ async function updateTransition(itemPath, reason, type, statusValue, message = '
367904
368044
  }
367905
368045
  k8sItem.status.conditions = updateConditionByType(k8sItem.status.conditions, type, conditionObject);
367906
368046
  const itemParameters = itemPath.split('/');
367907
- await writeStatus(itemParameters[1], itemParameters[0], k8sItem);
368047
+ await writePrioritizedStatus(itemParameters[1], itemParameters[0], k8sItem);
367908
368048
  }
367909
368049
  function getRelevantCondition(conditionList, type) {
367910
368050
  const condition = getConditionByType(conditionList, type);
@@ -368565,6 +368705,11 @@ const kindsWithFinalizer = [
368565
368705
  'FirestartrGithubOrgWebhook',
368566
368706
  'FirestartrGithubRepositorySecretsSection',
368567
368707
  ];
368708
+ const kindsWithDependants = [
368709
+ 'FirestartrDummyA',
368710
+ 'FirestartrDummyB',
368711
+ 'FirestartrGithubRepository',
368712
+ ];
368568
368713
  /**
368569
368714
  * Observe whenever a new item is added, modified or deleted in a given kind
368570
368715
  * @param {string} pluralKind - Kind to observe
@@ -368594,6 +368739,7 @@ async function observeKind(pluralKind, namespace, queue, compute) {
368594
368739
  async (item) => {
368595
368740
  operator_src_logger.info(`The informer has detected a new item, '${item.metadata.name}', for '${pluralKind}' in namespace '${namespace}'.`);
368596
368741
  await handleUpsertFinalizer(pluralKind, namespace, item);
368742
+ await upsertInitialStatus(pluralKind, namespace, item);
368597
368743
  const workItem = await inform(pluralKind, item, 'onAdd', getLastWorkItem(pluralKind, lastWorkItems, item));
368598
368744
  syncCtl.addItem(informer_itemPath(pluralKind, item));
368599
368745
  if (workItem) {
@@ -368675,6 +368821,28 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
368675
368821
  itemPath: () => informer_itemPath(pluralKind, workItem.item),
368676
368822
  error: () => retryCtl.errorReconciling(informer_itemPath(pluralKind, workItem.item)),
368677
368823
  success: () => retryCtl.successReconciling(informer_itemPath(pluralKind, workItem.item)),
368824
+ needsBlocking: (item) => {
368825
+ if (kindsWithDependants.indexOf(item.kind) === -1) {
368826
+ return false;
368827
+ }
368828
+ if (item.metadata.finalizers &&
368829
+ item.metadata.finalizers.indexOf('foregroundDeletion') !== -1) {
368830
+ // it will block for five seconds
368831
+ workItem.isBlocked = true;
368832
+ const tTimeout = setTimeout(() => {
368833
+ workItem.isBlocked = false;
368834
+ }, 1000 * 5);
368835
+ workItem.fUnblock = () => {
368836
+ clearTimeout(tTimeout);
368837
+ workItem.isBlocked = false;
368838
+ };
368839
+ return true;
368840
+ }
368841
+ else {
368842
+ workItem.isBlocked = false;
368843
+ return false;
368844
+ }
368845
+ },
368678
368846
  };
368679
368847
  workItem.process = async function* (item, operation, handler) {
368680
368848
  const needsUpdateSyncConditions = operation === OperationType.RENAMED ||
@@ -368703,6 +368871,7 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
368703
368871
  operator_src_logger.debug(`The informer received an item with an operation type of '${operation}', which is not a specific operation.`);
368704
368872
  }
368705
368873
  };
368874
+ workItem.isBlocked = false;
368706
368875
  queue(workItem);
368707
368876
  }
368708
368877
  function informer_itemPath(kind, item) {
@@ -368727,6 +368896,7 @@ function setLastWorkItem(kind, workItemsMap, item, workItem) {
368727
368896
  */
368728
368897
  async function inform(pluralKind, item, op, lastWorkItem = null) {
368729
368898
  let workItem = lastWorkItem;
368899
+ let needed;
368730
368900
  if (getKindFromPlural(pluralKind) !== item.kind)
368731
368901
  return null;
368732
368902
  switch (op) {
@@ -368743,8 +368913,9 @@ async function inform(pluralKind, item, op, lastWorkItem = null) {
368743
368913
  };
368744
368914
  return workItem;
368745
368915
  case 'onRename':
368746
- if (await needsProvisioningOnCreate(item)) {
368747
- operator_src_logger.debug(`The informer is triggering a new provisioning process for the renamed item '${item.kind}/${item.metadata.name}'.`);
368916
+ needed = await needsProvisioningOnCreateOrUpdate(item);
368917
+ if (needed.needs) {
368918
+ operator_src_logger.debug(`The informer is triggering a new provisioning process for the renamed item '${item.kind}/${item.metadata.name}'. Reason: ${needed.reason}.`);
368748
368919
  workItem = {
368749
368920
  operation: OperationType.RENAMED,
368750
368921
  item,
@@ -368768,9 +368939,12 @@ async function inform(pluralKind, item, op, lastWorkItem = null) {
368768
368939
  };
368769
368940
  return workItem;
368770
368941
  case 'onAdd':
368771
- if (await needsProvisioningOnCreate(item)) {
368942
+ needed = await needsProvisioningOnCreateOrUpdate(item);
368943
+ if (needed.needs) {
368772
368944
  workItem = {
368773
- operation: OperationType.CREATED,
368945
+ operation: needed.reason === 'CREATED'
368946
+ ? OperationType.CREATED
368947
+ : OperationType.UPDATED,
368774
368948
  item,
368775
368949
  workStatus: WorkStatus.PENDING,
368776
368950
  onDelete: function () { },
@@ -368926,10 +369100,72 @@ function dummy_fWait(ms) {
368926
369100
  });
368927
369101
  }
368928
369102
 
369103
+ ;// CONCATENATED MODULE: ../operator/src/ownership.ts
369104
+
369105
+
369106
+
369107
+ async function getOwnerReferences(item) {
369108
+ return item.metadata?.ownerReferences || [];
369109
+ }
369110
+ async function setOwnerReference(itemPath, namespace, ownerKind, ownerName, blockOwnerDeletion = true) {
369111
+ let item = null;
369112
+ try {
369113
+ // we need to search for the owner's uuid
369114
+ const owner = await getItemByItemPath(`${namespace}/${ownerKind}/${ownerName}`);
369115
+ const ownerReference = {
369116
+ apiVersion: owner.apiVersion,
369117
+ kind: owner.kind,
369118
+ name: ownerName,
369119
+ controller: true,
369120
+ blockOwnerDeletion,
369121
+ uid: owner.metadata.uid,
369122
+ };
369123
+ // we get the item (to prevent race conditions)
369124
+ item = await getItemByItemPath(itemPath);
369125
+ const ownerReferences = item.metadata.ownerReferences ?? [];
369126
+ const existingRefIndex = ownerReferences.findIndex((ref) => ref.uid === ownerReference.uid);
369127
+ if (existingRefIndex === -1) {
369128
+ // Reference does not exist, add it
369129
+ ownerReferences.push(ownerReference);
369130
+ }
369131
+ else {
369132
+ ownerReferences[existingRefIndex] = ownerReference;
369133
+ }
369134
+ await writeOwnerReferences(definitions_getPluralFromKind(item.kind), item.metadata.namespace, item, ownerReferences);
369135
+ }
369136
+ catch (err) {
369137
+ operator_src_logger.error(err);
369138
+ throw `Setting OwnerReferences to ${item.kind}/${item.metadata.name}: ${err}`;
369139
+ }
369140
+ }
369141
+ async function writeOwnerReferences(kind, namespace, item, ownerReferences) {
369142
+ operator_src_logger.debug(`The ctl is setting the ownerReferences for '${kind}/${item.metadata.name}' in namespace '${namespace}'.`);
369143
+ const { kc, opts } = await ctl_getConnection();
369144
+ const url = `${kc.getCurrentCluster().server}/apis/firestartr.dev/v1/namespaces/${namespace}/${kind}/${item.metadata.name}`;
369145
+ opts.headers['Content-Type'] = 'application/json-patch+json';
369146
+ opts.headers['Accept'] = '*';
369147
+ const patch = {
369148
+ op: 'replace',
369149
+ path: '/metadata/ownerReferences',
369150
+ value: ownerReferences,
369151
+ };
369152
+ const r = await fetch(url, {
369153
+ method: 'PATCH',
369154
+ headers: opts.headers,
369155
+ body: JSON.stringify([patch]),
369156
+ });
369157
+ if (!r.ok) {
369158
+ throw `Error on setOwnerReferences: ${namespace}/${kind}/${item['metadata']['name']}: ${r.statusText}`;
369159
+ }
369160
+ return r.json();
369161
+ }
369162
+
368929
369163
  ;// CONCATENATED MODULE: ../operator/fdummies/index.ts
368930
369164
 
368931
369165
 
368932
369166
 
369167
+
369168
+
368933
369169
  function processFirestartrDummies(item, op, handler) {
368934
369170
  operator_src_logger.info(`FirestartrDummies Processor: ${op}`);
368935
369171
  try {
@@ -368960,11 +369196,19 @@ async function* updated(item, op, handler) {
368960
369196
  for await (const transition of doRun(item, op, handler)) {
368961
369197
  yield transition;
368962
369198
  }
369199
+ await handleOwnerReferences(item, handler);
368963
369200
  }
368964
369201
  async function* created(item, op, handler) {
368965
369202
  for await (const transition of doRun(item, op, handler)) {
368966
369203
  yield transition;
368967
369204
  }
369205
+ await handleOwnerReferences(item, handler);
369206
+ }
369207
+ async function handleOwnerReferences(item, handler) {
369208
+ if ('needs' in item.spec) {
369209
+ const needs = item.spec.needs;
369210
+ await setOwnerReference(handler.itemPath(), item.metadata.namespace, definitions_getPluralFromKind(needs.kind), needs.name);
369211
+ }
368968
369212
  }
368969
369213
  async function renamed() {
368970
369214
  throw new Error('Renamed operation not prepared');
@@ -369035,7 +369279,7 @@ async function* markedToDeletion(item, op, handler) {
369035
369279
  message: 'Destroying process started',
369036
369280
  };
369037
369281
  await handler.resolveReferences();
369038
- await processDummy(item);
369282
+ await processDummy(item, op);
369039
369283
  yield {
369040
369284
  item,
369041
369285
  reason: op,
@@ -369104,7 +369348,7 @@ async function* doRun(item, op, handler) {
369104
369348
  };
369105
369349
  const deps = await handler.resolveReferences();
369106
369350
  operator_src_logger.info(`The dummy processor is applying and assessing dependencies for item '${item.kind}/${item.metadata.name}' with dependencies: '${deps}'.`);
369107
- await processDummy(item);
369351
+ await processDummy(item, op);
369108
369352
  yield {
369109
369353
  item,
369110
369354
  reason: op,
@@ -369160,11 +369404,13 @@ async function* doRun(item, op, handler) {
369160
369404
  }
369161
369405
  }
369162
369406
  }
369163
- async function processDummy(item) {
369164
- const s = item.spec?.computation?.numberOfSeconds;
369165
- operator_src_logger.info(`Processing dummy ${item.kind}/${item.metadata.name}: computing for ${s} seconds`);
369407
+ async function processDummy(item, op) {
369408
+ const s = op === OperationType.MARKED_TO_DELETION
369409
+ ? item.spec?.computation?.numberOfSecondsToDestroy
369410
+ : item.spec?.computation?.numberOfSeconds;
369411
+ operator_src_logger.info(`Processing dummy (op = ${op}) ${item.kind}/${item.metadata.name}: computing for ${s} seconds`);
369166
369412
  if (!s)
369167
- throw new Error('Unprocessable dummy: missing seconds section');
369413
+ throw new Error('Unprocessable dummy: no seconds section');
369168
369414
  await fdummies_fWait(s * 1000);
369169
369415
  }
369170
369416
  function fdummies_fWait(ms) {
@@ -369197,7 +369443,8 @@ async function writeDownQueueStatus(queue) {
369197
369443
  let output = '';
369198
369444
  for (const workItem of queue) {
369199
369445
  const item = workItem.item;
369200
- output += `${item.kind}/${item.metadata.name} - ${workItem.workStatus} - ${workItem.operation} - (upsert ${formatElapsedTimeWithDate(workItem.upsertTime)})\n`;
369446
+ const blockedText = workItem.isBlocked ? '[BLOCKED]' : '';
369447
+ output += `${item.kind}/${item.metadata.name} - ${workItem.workStatus} - ${workItem.operation} ${blockedText} - (upsert ${formatElapsedTimeWithDate(workItem.upsertTime)})\n`;
369201
369448
  }
369202
369449
  return new Promise((ok, ko) => {
369203
369450
  external_fs_.writeFile('/tmp/queue', output, (err) => {
@@ -369278,6 +369525,58 @@ async function deadLetterHandler(workItem) {
369278
369525
  }
369279
369526
  }
369280
369527
 
369528
+ ;// CONCATENATED MODULE: ../operator/src/signals.ts
369529
+
369530
+ const DEFAULT_TERMINATION_GRACE_PERIOD = 2 * 60; // two minutes
369531
+ /**
369532
+ * Initializes process signal handlers used by the operator.
369533
+ *
369534
+ * Currently this sets up handling for `SIGTERM`, using the callback
369535
+ * associated with the `"SIGTERM"` key from the provided {@link CallbacksMap}
369536
+ * to start the shutdown sequence. The returned {@link CallbacksMap} contains
369537
+ * handler-specific callbacks (such as `"FINISH_OK"`) that callers can invoke
369538
+ * to indicate that it is safe for the process to exit.
369539
+ *
369540
+ * @param callbacks A map of signal names to shutdown callbacks. The `"SIGTERM"`
369541
+ * entry (if present) is invoked when a `SIGTERM` signal is received to
369542
+ * perform any necessary cleanup before process termination.
369543
+ * @returns A {@link CallbacksMap} with control callbacks that allow the caller
369544
+ * to signal when shutdown has completed and the process may safely exit.
369545
+ */
369546
+ function initSignalsHandler(callbacks) {
369547
+ operator_src_logger.info('Starting signals handler');
369548
+ const handlerCallbacks = new Map();
369549
+ initSigtermHandler(callbacks.get('SIGTERM'), handlerCallbacks);
369550
+ return handlerCallbacks;
369551
+ }
369552
+ function initSigtermHandler(callback, handlerCallbacks) {
369553
+ const raw_timeout_to_exit = Number(process.env['FIRESTARTR_TERMINATION_GRACE_PERIOD'] ||
369554
+ DEFAULT_TERMINATION_GRACE_PERIOD);
369555
+ const timeout_to_exit = raw_timeout_to_exit - Math.round(Math.min(5, raw_timeout_to_exit * 0.1));
369556
+ // The switch to control if it is safe to exit
369557
+ let finish = false;
369558
+ handlerCallbacks.set('FINISH_OK', () => {
369559
+ finish = true;
369560
+ });
369561
+ process.on('SIGTERM', async () => {
369562
+ operator_src_logger.info('The controller received a SIGTERM signal');
369563
+ // we signal to the callback the sigterm
369564
+ callback();
369565
+ const timeoutCb = setTimeout(() => {
369566
+ operator_src_logger.error('The controller could not shutdown properly. Timeout');
369567
+ process.exit(1);
369568
+ }, timeout_to_exit * 1000);
369569
+ // we wait
369570
+ while (!finish) {
369571
+ await new Promise((resolve) => setTimeout(resolve, 1000));
369572
+ }
369573
+ // all is clear!
369574
+ clearTimeout(timeoutCb);
369575
+ operator_src_logger.info('The controller has properly shutdown. Exiting');
369576
+ process.exit(0);
369577
+ });
369578
+ }
369579
+
369281
369580
  ;// CONCATENATED MODULE: ../operator/src/processItem.ts
369282
369581
 
369283
369582
 
@@ -369285,6 +369584,7 @@ async function deadLetterHandler(workItem) {
369285
369584
 
369286
369585
 
369287
369586
 
369587
+
369288
369588
  const queue = [];
369289
369589
  const WEIGHTS = {
369290
369590
  RENAMED: 15,
@@ -369390,9 +369690,19 @@ async function processItem(workItem) {
369390
369690
  * @returns {void}
369391
369691
  */
369392
369692
  async function processItem_loop() {
369393
- const nextWorkItem = () => sortQueue(queue).find((w) => w.workStatus === WorkStatus.PENDING);
369693
+ const nextWorkItem = () => sortQueue(queue)
369694
+ .filter((w) => !w.isBlocked)
369695
+ .find((w) => w.workStatus === WorkStatus.PENDING);
369394
369696
  loopWorkItemDebug(queue);
369697
+ let podIsTerminating = false;
369698
+ const handlerCallbacks = initSignalsHandler(new Map([['SIGTERM', () => (podIsTerminating = true)]]));
369395
369699
  while (1) {
369700
+ if (podIsTerminating) {
369701
+ operator_src_logger.info('The processor is going to shutdown (pod is terminating)');
369702
+ // we notify the handler that is ok to shutdown
369703
+ handlerCallbacks.get('FINISH_OK')();
369704
+ break;
369705
+ }
369396
369706
  const w = nextWorkItem();
369397
369707
  if (w) {
369398
369708
  const logMessage = `${new Date().toISOString()} : Processing OPERATION: ${w.operation} ITEM: ${w.item.kind}/${w.item.metadata.name}`;
@@ -369454,6 +369764,14 @@ async function runWorkItem(workItem) {
369454
369764
  return;
369455
369765
  try {
369456
369766
  const item = await workItem.getItem();
369767
+ // we check if the workItem needs blocking
369768
+ // if it does need it we return because we cannot
369769
+ // process this item
369770
+ if ('needsBlocking' in workItem.handler &&
369771
+ workItem.handler.needsBlocking(item)) {
369772
+ operator_src_logger.debug(`Item ${item.kind}/${item.metadata.namespace} needs blocking`);
369773
+ return;
369774
+ }
369457
369775
  workItem.workStatus = WorkStatus.PROCESSING;
369458
369776
  for await (const condition of workItem.process(item, workItem.operation, workItem.handler)) {
369459
369777
  if (workItem.handler === undefined)
@@ -369844,9 +370162,10 @@ var actions_repository_oidc_subject_claim_customization_template = __nccwpck_req
369844
370162
  function provisionOIDCSubjectClaim(scope, repo, fsGithubRepository) {
369845
370163
  const tfStateKey = `_${fsGithubRepository.getTfStateKey()}-oidc-subject-claim-template`;
369846
370164
  const claimKeys = fsGithubRepository.spec.actions.oidc.includeClaimKeys;
370165
+ const useDefault = fsGithubRepository.spec.actions.oidc.useDefault;
369847
370166
  const config = {
369848
370167
  repository: repo.name,
369849
- useDefault: claimKeys.length < 1,
370168
+ useDefault,
369850
370169
  };
369851
370170
  if (claimKeys.length > 0) {
369852
370171
  config['includeClaimKeys'] = claimKeys;
@@ -371450,19 +371769,19 @@ if (process.env.RUN_PROVISIONER) {
371450
371769
 
371451
371770
 
371452
371771
  const LAST_STATE_PR_ANNOTATION = 'firestartr.dev/last-state-pr';
371453
- async function tryPublishApply(item, planOutput, kind) {
371772
+ async function tryPublishApply(item, planOutput, kind, isSuccess = true) {
371454
371773
  try {
371455
371774
  if (!(LAST_STATE_PR_ANNOTATION in item.metadata.annotations)) {
371456
371775
  operator_src_logger.debug(`The user feedback for the '${kind}/${item.metadata.name}' apply operation could not be published because the last state was not found.`);
371457
371776
  return;
371458
371777
  }
371459
- await publishApply(item, planOutput, kind);
371778
+ await publishApply(item, planOutput, kind, isSuccess);
371460
371779
  }
371461
371780
  catch (e) {
371462
371781
  operator_src_logger.error(`The user feedback for the '${kind}/${item.metadata.name}' apply operation failed to publish due to an error: '${e}'.`);
371463
371782
  }
371464
371783
  }
371465
- async function tryPublishDestroy(item, destroyOutput) {
371784
+ async function tryPublishDestroy(item, destroyOutput, isSuccess = true) {
371466
371785
  let lastPr = null;
371467
371786
  try {
371468
371787
  const { repo, org } = extractPrInfo(item);
@@ -371481,11 +371800,13 @@ async function tryPublishDestroy(item, destroyOutput) {
371481
371800
  return;
371482
371801
  }
371483
371802
  const dividedOutput = github_0.pulls.divideCommentIntoChunks(destroyOutput, 250);
371803
+ const statusEmoji = isSuccess ? '✅' : '❌';
371804
+ const statusText = isSuccess ? 'Succeeded' : 'Failed';
371484
371805
  const commentBodies = dividedOutput.map((commentContent, index) => {
371485
371806
  const isMultiPart = dividedOutput.length > 1;
371486
371807
  const partIndicator = isMultiPart ? ` (Part ${index + 1})` : '';
371487
371808
  return `<h1>
371488
- <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Destroy Finished
371809
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Destroy ${statusText} ${statusEmoji}
371489
371810
  </h1>
371490
371811
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
371491
371812
 
@@ -371513,14 +371834,16 @@ ${commentContent}
371513
371834
  operator_src_logger.error(`An error occurred while publishing user feedback for item '${item.kind}/${item.metadata.name}': '${e}'.`);
371514
371835
  }
371515
371836
  }
371516
- async function publishApply(item, applyOutput, kind) {
371837
+ async function publishApply(item, applyOutput, kind, isSuccess = true) {
371517
371838
  const { prNumber, repo, org } = extractPrInfo(item);
371518
371839
  const dividedOutput = github_0.pulls.divideCommentIntoChunks(applyOutput, 250);
371840
+ const statusEmoji = isSuccess ? '✅' : '❌';
371841
+ const statusText = isSuccess ? 'Succeeded' : 'Failed';
371519
371842
  const commentBodies = dividedOutput.map((commentContent, index) => {
371520
371843
  const isMultiPart = dividedOutput.length > 1;
371521
371844
  const partIndicator = isMultiPart ? ` (Part ${index + 1})` : '';
371522
371845
  return `<h1>
371523
- <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Apply Finished
371846
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Apply ${statusText} ${statusEmoji}
371524
371847
  </h1>
371525
371848
  <p><b>${kind}: </b>${item.metadata.name}</p>
371526
371849
 
@@ -371595,14 +371918,16 @@ ${message}
371595
371918
  `;
371596
371919
  await github_0.pulls.commentInPR(comment, prNumber, repo, org, 'logs');
371597
371920
  }
371598
- async function publishPlan(item, planOutput, prNumber, repo, org) {
371921
+ async function publishPlan(item, planOutput, prNumber, repo, org, isSuccess = true) {
371599
371922
  try {
371600
371923
  const dividedOutput = github_0.pulls.divideCommentIntoChunks(planOutput, 250);
371924
+ const statusEmoji = isSuccess ? '✅' : '❌';
371925
+ const statusText = isSuccess ? 'Succeeded' : 'Failed';
371601
371926
  const commentBodies = dividedOutput.map((commentContent, index) => {
371602
371927
  const isMultiPart = dividedOutput.length > 1;
371603
371928
  const partIndicator = isMultiPart ? ` (Part ${index + 1})` : '';
371604
371929
  return `<h1>
371605
- <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan Finished
371930
+ <img width="25" src="https://raw.githubusercontent.com/firestartr-pro/docs/refs/heads/main/logos/square-nobg.png"> Plan ${statusText} ${statusEmoji}
371606
371931
  </h1>
371607
371932
  <p><b>TFWorkspace: </b>${item.metadata.name}</p>
371608
371933
 
@@ -371663,6 +371988,33 @@ function helperCreateCheckRunName(cmd, item) {
371663
371988
  return `${item.kind} - ${cmd}`;
371664
371989
  }
371665
371990
 
371991
+ ;// CONCATENATED MODULE: ../operator/src/cdktf/ownership.ts
371992
+
371993
+
371994
+
371995
+ const kindsWithFirestartrGithubRepositoryDependence = [
371996
+ 'FirestartrGithubRepositorySecretsSection',
371997
+ 'FirestartrGithubRepositoryFeature',
371998
+ ];
371999
+ async function manageOwnershipReferences(item, handler, op) {
372000
+ if (kindsWithFirestartrGithubRepositoryDependence.indexOf(item.kind) !== -1) {
372001
+ await manageOwnershipReferencesForRepo(item, handler, op);
372002
+ }
372003
+ }
372004
+ async function manageOwnershipReferencesForRepo(item, handler, op) {
372005
+ try {
372006
+ const repositoryTarget = item.spec?.repositoryTarget?.ref;
372007
+ if (!repositoryTarget) {
372008
+ throw `Item ${item.kind}/${item.metadata.namespace} is not correct: it does not have a repositoryTarget`;
372009
+ }
372010
+ await setOwnerReference(handler.itemPath(), item.metadata.namespace, definitions_getPluralFromKind(repositoryTarget.kind), repositoryTarget.name);
372011
+ }
372012
+ catch (err) {
372013
+ operator_src_logger.error(`Handling ownership for ${item.kind}/${item.metadata.name}: ${err}`);
372014
+ throw new Error(`Handling ownership for ${item.kind}/${item.metadata.name}: ${err}`);
372015
+ }
372016
+ }
372017
+
371666
372018
  ;// CONCATENATED MODULE: ../operator/cdktf.ts
371667
372019
 
371668
372020
 
@@ -371673,6 +372025,7 @@ function helperCreateCheckRunName(cmd, item) {
371673
372025
 
371674
372026
 
371675
372027
 
372028
+
371676
372029
  function processOperation(item, op, handler) {
371677
372030
  operator_src_logger.info(`Processing operation ${op} on ${item.kind}/${item.metadata?.name}`);
371678
372031
  try {
@@ -371704,16 +372057,19 @@ async function* cdktf_created(item, op, handler) {
371704
372057
  for await (const transition of doApply(item, op, handler)) {
371705
372058
  yield transition;
371706
372059
  }
372060
+ await manageOwnershipReferences(item, handler, op);
371707
372061
  }
371708
372062
  async function* cdktf_renamed(item, op, handler) {
371709
372063
  for await (const transition of doApply(item, op, handler)) {
371710
372064
  yield transition;
371711
372065
  }
372066
+ await manageOwnershipReferences(item, handler, op);
371712
372067
  }
371713
372068
  async function* cdktf_updated(item, op, handler) {
371714
372069
  for await (const transition of doApply(item, op, handler)) {
371715
372070
  yield transition;
371716
372071
  }
372072
+ await manageOwnershipReferences(item, handler, op);
371717
372073
  }
371718
372074
  async function* cdktf_retry(item, op, handler) {
371719
372075
  if ('deletionTimestamp' in item.metadata) {
@@ -371809,7 +372165,6 @@ async function* cdktf_markedToDeletion(item, op, handler) {
371809
372165
  : {}),
371810
372166
  });
371811
372167
  const output = destroyOutput.output;
371812
- await tryPublishDestroy(item, output);
371813
372168
  yield {
371814
372169
  item,
371815
372170
  reason: op,
@@ -371822,15 +372177,24 @@ async function* cdktf_markedToDeletion(item, op, handler) {
371822
372177
  if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
371823
372178
  await addDestroyCommitStatus(item, 'success', 'Destroy operation completed', `Terraform Destroy ${item.metadata.name}`);
371824
372179
  }
372180
+ await tryPublishDestroy(item, output, true);
371825
372181
  void handler.success();
371826
372182
  }
371827
372183
  catch (e) {
371828
372184
  error = true;
372185
+ let errorMsg;
372186
+ if (typeof e === 'object' && 'output' in e) {
372187
+ errorMsg = e.output;
372188
+ }
372189
+ else {
372190
+ errorMsg = e;
372191
+ }
371829
372192
  // if there is a current checkRun working
371830
372193
  // we close it with an error
371831
372194
  if (checkRunCtl)
371832
- checkRunCtl.fnOnError(e);
371833
- await handler.writeTerraformOutputInTfResult(item, e);
372195
+ checkRunCtl.fnOnError(errorMsg);
372196
+ await tryPublishDestroy(item, errorMsg, false);
372197
+ await handler.writeTerraformOutputInTfResult(item, errorMsg);
371834
372198
  void handler.error();
371835
372199
  }
371836
372200
  finally {
@@ -371938,7 +372302,6 @@ async function* doApply(item, op, handler) {
371938
372302
  }
371939
372303
  : {}),
371940
372304
  });
371941
- await tryPublishApply(item, applyOutput?.data?.output, item.kind);
371942
372305
  const terraformOutputJson = await provisioner.runTerraform(item, ['output', '-json'], null);
371943
372306
  if (!terraformOutputJson) {
371944
372307
  throw new Error(`Terraform output is empty for ${item.kind}/${item.metadata.name}`);
@@ -371967,7 +372330,8 @@ async function* doApply(item, op, handler) {
371967
372330
  message: 'doApply',
371968
372331
  };
371969
372332
  await handler.writeTerraformOutputInTfResult(item, output);
371970
- handler.success();
372333
+ await tryPublishApply(item, applyOutput?.data?.output, item.kind, true);
372334
+ void handler.success();
371971
372335
  }
371972
372336
  catch (e) {
371973
372337
  error = true;
@@ -373554,7 +373918,6 @@ async function* process_operation_markedToDeletion(item, op, handler) {
373554
373918
  const deps = await handler.resolveReferences();
373555
373919
  const context = buildProvisionerContext(item, deps);
373556
373920
  const destroyOutput = await runTerraformProvisioner(context, 'destroy');
373557
- await tryPublishDestroy(item, destroyOutput);
373558
373921
  yield {
373559
373922
  item,
373560
373923
  reason: op,
@@ -373574,11 +373937,20 @@ async function* process_operation_markedToDeletion(item, op, handler) {
373574
373937
  if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
373575
373938
  await addDestroyCommitStatus(item, 'success', 'Destroy operation completed', `Terraform Destroy ${item.metadata.name}`);
373576
373939
  }
373940
+ await tryPublishDestroy(item, destroyOutput, true);
373577
373941
  void handler.success();
373578
373942
  }
373579
373943
  catch (e) {
373580
373944
  error = true;
373581
- await handler.writeTerraformOutputInTfResult(item, e);
373945
+ let errorMsg;
373946
+ if (typeof e === 'object' && 'output' in e) {
373947
+ errorMsg = e.output;
373948
+ }
373949
+ else {
373950
+ errorMsg = e;
373951
+ }
373952
+ await tryPublishDestroy(item, errorMsg, false);
373953
+ await handler.writeTerraformOutputInTfResult(item, errorMsg);
373582
373954
  if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
373583
373955
  await addDestroyCommitStatus(item, 'failure', 'Destroy operation failed', `Terraform Destroy ${item.metadata.name}`);
373584
373956
  }
@@ -373663,7 +374035,6 @@ async function* process_operation_doApply(item, op, handler) {
373663
374035
  operator_src_logger.info(`The Terraform processor is applying and assessing dependencies for item '${item.kind}/${item.metadata.name}' with dependencies: '${deps}'.`);
373664
374036
  const context = buildProvisionerContext(item, deps);
373665
374037
  const applyOutput = await runTerraformProvisioner(context, 'apply', checkRunCtl);
373666
- await tryPublishApply(item, applyOutput, 'TFWorkspace');
373667
374038
  const terraformOutputJson = await runTerraformProvisioner(context, 'output');
373668
374039
  if (!terraformOutputJson) {
373669
374040
  throw new Error(`Terraform output is empty for ${item.kind}/${item.metadata.name}`);
@@ -373694,17 +374065,25 @@ async function* process_operation_doApply(item, op, handler) {
373694
374065
  message: 'doApply',
373695
374066
  };
373696
374067
  await handler.writeTerraformOutputInTfResult(item, output);
374068
+ await tryPublishApply(item, applyOutput, 'TFWorkspace', true);
373697
374069
  handler.success();
373698
374070
  }
373699
374071
  catch (e) {
373700
374072
  error = true;
373701
- checkRunCtl.fnOnError(e);
374073
+ let errorMsg;
374074
+ if (typeof e === 'object' && 'output' in e) {
374075
+ errorMsg = e.output;
374076
+ }
374077
+ else {
374078
+ errorMsg = e;
374079
+ }
374080
+ checkRunCtl.fnOnError(errorMsg);
373702
374081
  console.error(e);
373703
- await tryPublishApply(item, e, 'TFWorkspace');
374082
+ await tryPublishApply(item, errorMsg, 'TFWorkspace', false);
373704
374083
  operator_src_logger.error(`The Terraform processor encountered an error during operation '${op}' for item '${item.kind}/${item.metadata.name}': '${e}'.`);
373705
374084
  handler.error();
373706
- if (e) {
373707
- await handler.writeTerraformOutputInTfResult(item, e);
374085
+ if (errorMsg) {
374086
+ await handler.writeTerraformOutputInTfResult(item, errorMsg);
373708
374087
  }
373709
374088
  }
373710
374089
  finally {
@@ -373951,7 +374330,6 @@ function clearLocalTfProjects() {
373951
374330
  external_fs_.rmSync(TF_PROJECTS_PATH, { recursive: true, force: true });
373952
374331
  }
373953
374332
  function getErrorOutputMessage(cr, key, ref) {
373954
- const result = '';
373955
374333
  if (cr.spec.source === 'Remote') {
373956
374334
  return `
373957
374335
 
@@ -374170,8 +374548,6 @@ async function* doPlanPlainTextFormat(item, op, handler, action) {
374170
374548
  await addPlanStatusCheck(item.metadata.annotations['firestartr.dev/last-state-pr'], 'Terraform plan in progress...');
374171
374549
  }
374172
374550
  const tfPlanOutput = await runTerraformProvisioner(context, action);
374173
- const { prNumber, repo, org } = extractPrInfo(item, 'firestartr.dev/pull-request-plan');
374174
- await publishPlan(item, tfPlanOutput, prNumber, repo, org);
374175
374551
  yield {
374176
374552
  item,
374177
374553
  reason: op,
@@ -374196,11 +374572,13 @@ async function* doPlanPlainTextFormat(item, op, handler, action) {
374196
374572
  if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
374197
374573
  await addPlanStatusCheck(item.metadata.annotations['firestartr.dev/last-state-pr'], tfPlanOutput, 'completed');
374198
374574
  }
374575
+ const { prNumber, repo, org } = extractPrInfo(item, 'firestartr.dev/pull-request-plan');
374576
+ await publishPlan(item, tfPlanOutput, prNumber, repo, org, true);
374199
374577
  }
374200
374578
  catch (e) {
374201
374579
  error = true;
374202
374580
  const { prNumber, repo, org } = extractPrInfo(item, 'firestartr.dev/pull-request-plan');
374203
- await publishPlan(item, JSON.stringify(e), prNumber, repo, org);
374581
+ await publishPlan(item, JSON.stringify(e), prNumber, repo, org, false);
374204
374582
  operator_src_logger.error('TFWORKSPACE_PROCESSOR_PLAN_OBSERVING_ERROR', {
374205
374583
  metadata: { item, error: e },
374206
374584
  });
@@ -375806,6 +376184,10 @@ const crs_analyzerSubcommand = {
375806
376184
  },
375807
376185
  };
375808
376186
 
376187
+ ;// CONCATENATED MODULE: ./package.json
376188
+ const package_namespaceObject = JSON.parse('{"i8":"1.55.0-snapshot-1"}');
376189
+ ;// CONCATENATED MODULE: ../../package.json
376190
+ const package_namespaceObject_1 = {"i8":"1.54.0"};
375809
376191
  ;// CONCATENATED MODULE: ./src/subcommands/index.ts
375810
376192
 
375811
376193
 
@@ -375814,6 +376196,8 @@ const crs_analyzerSubcommand = {
375814
376196
 
375815
376197
 
375816
376198
 
376199
+
376200
+
375817
376201
  const SUBCOMMANDS = {
375818
376202
  import: importSubcommand,
375819
376203
  importer: importSubcommand,
@@ -375851,6 +376235,9 @@ function showSubcommandsHelp() {
375851
376235
  console.log('AVAILABLE COMMANDS');
375852
376236
  console.table(commandsList);
375853
376237
  }
376238
+ function showCliVersion() {
376239
+ console.log(`CLI Version: ${package_namespaceObject.i8}. Firestartr Version: ${package_namespaceObject_1.i8}`);
376240
+ }
375854
376241
 
375855
376242
  ;// CONCATENATED MODULE: ./src/command_line.ts
375856
376243
 
@@ -375871,6 +376258,9 @@ class CommandLine {
375871
376258
  case 'help':
375872
376259
  showSubcommandsHelp();
375873
376260
  break;
376261
+ case 'version':
376262
+ showCliVersion();
376263
+ break;
375874
376264
  default: {
375875
376265
  // Get the subcommand data
375876
376266
  const subcommandData = validateAndGetSubcommand(subcommand);
@@ -1,3 +1,4 @@
1
1
  import { Subcommand } from '../types';
2
2
  export declare function validateAndGetSubcommand(name: string): Subcommand;
3
3
  export declare function showSubcommandsHelp(): void;
4
+ export declare function showCliVersion(): void;
@@ -1,3 +1,4 @@
1
1
  export default function render(featurePath: string, featureRenderPath: string, entity: any, firestartrConfig?: any, featureArgs?: any): any;
2
2
  export declare function buildContext(entity: any, args: any, firestartrConfig: any, featureArgs: any): any;
3
+ export declare function expandFiles(featurePath: string, configData: any, context: any): void;
3
4
  export declare function renderContent(template: string, ctx: any): string;
@@ -29,6 +29,13 @@ declare const _default: {
29
29
  };
30
30
  };
31
31
  };
32
+ filesTemplates: {
33
+ type: string;
34
+ description: string;
35
+ items: {
36
+ type: string;
37
+ };
38
+ };
32
39
  };
33
40
  required: string[];
34
41
  title: string;
@@ -48,7 +55,7 @@ declare const _default: {
48
55
  additionalProperties: boolean;
49
56
  properties: {
50
57
  $lit: {
51
- type: string;
58
+ type: string[];
52
59
  };
53
60
  $ref: {
54
61
  type: string;
@@ -59,6 +66,9 @@ declare const _default: {
59
66
  $arg: {
60
67
  type: string;
61
68
  };
69
+ $template: {
70
+ type: string;
71
+ };
62
72
  $default: {
63
73
  type: string[];
64
74
  };
@@ -0,0 +1,2 @@
1
+ import { OperationType } from '../informer';
2
+ export declare function manageOwnershipReferences(item: any, handler: any, op: OperationType): Promise<void>;
@@ -0,0 +1 @@
1
+ export declare function setHighPriorityStatus(item: any): void;
@@ -23,6 +23,8 @@ export type WorkItem = {
23
23
  process?: Function;
24
24
  upsertTime?: number;
25
25
  isDeadLetter?: boolean;
26
+ isBlocked?: boolean;
27
+ fUnblock?: Function;
26
28
  };
27
29
  type HandlerFinalizerFn = (kind: string, namespace: string, item: any | string, finalizer: string) => Promise<any>;
28
30
  type HandlerInformPlanFn = (prUrl: string, planText: string) => Promise<void>;
@@ -44,6 +46,9 @@ export type WorkItemHandler = {
44
46
  itemPath: ItemPathFn;
45
47
  error: ErrorFn;
46
48
  success: SuccessFn;
49
+ isBlocked?: boolean;
50
+ needsBlocking?: (item: any) => boolean;
51
+ fUnblock?: Function;
47
52
  };
48
53
  /**
49
54
  * Observe whenever a new item is added, modified or deleted in a given kind
@@ -0,0 +1,4 @@
1
+ import { OwnerReference } from './types';
2
+ export declare function getOwnerReferences(item: any): Promise<OwnerReference[]>;
3
+ export declare function setOwnerReference(itemPath: string, namespace: string, ownerKind: string, ownerName: string, blockOwnerDeletion?: boolean): Promise<void>;
4
+ export declare function writeOwnerReferences(kind: string, namespace: string, item: any, ownerReferences: OwnerReference[]): Promise<any>;
@@ -0,0 +1,17 @@
1
+ export type CallbacksMap = Map<string, () => void>;
2
+ /**
3
+ * Initializes process signal handlers used by the operator.
4
+ *
5
+ * Currently this sets up handling for `SIGTERM`, using the callback
6
+ * associated with the `"SIGTERM"` key from the provided {@link CallbacksMap}
7
+ * to start the shutdown sequence. The returned {@link CallbacksMap} contains
8
+ * handler-specific callbacks (such as `"FINISH_OK"`) that callers can invoke
9
+ * to indicate that it is safe for the process to exit.
10
+ *
11
+ * @param callbacks A map of signal names to shutdown callbacks. The `"SIGTERM"`
12
+ * entry (if present) is invoked when a `SIGTERM` signal is received to
13
+ * perform any necessary cleanup before process termination.
14
+ * @returns A {@link CallbacksMap} with control callbacks that allow the caller
15
+ * to signal when shutdown has completed and the process may safely exit.
16
+ */
17
+ export declare function initSignalsHandler(callbacks: CallbacksMap): CallbacksMap;
@@ -1,4 +1,10 @@
1
- export declare function needsProvisioningOnCreate(cr: any): Promise<boolean>;
1
+ export type NeedsCreationOrUpdate = {
2
+ needs: boolean;
3
+ reason?: string;
4
+ };
5
+ export declare function upsertInitialStatus(pluralKind: string, namespace: string, item: any): Promise<void>;
6
+ export declare function needsProvisioningOnCreateOrUpdate(cr: any): Promise<NeedsCreationOrUpdate>;
2
7
  export declare function updateSyncTransition(itemPath: string, reason: string, lastSyncTime: string, nextSyncTime: string, message: string, status: string): Promise<void>;
8
+ export declare function writePrioritizedStatus(kind: string, namespace: string, item: any): Promise<void>;
3
9
  export declare function updateTransition(itemPath: string, reason: string, type: string, statusValue: string, message?: string, updateStatusOnly?: boolean): Promise<void>;
4
10
  export declare function getConditionByType(conditionList: Array<any>, type: string): any;
@@ -0,0 +1,8 @@
1
+ export interface OwnerReference {
2
+ apiVersion: string;
3
+ kind: string;
4
+ name: string;
5
+ uid: string;
6
+ controller?: boolean;
7
+ blockOwnerDeletion?: boolean;
8
+ }
@@ -1,6 +1,6 @@
1
- export declare function tryPublishApply(item: any, planOutput: string, kind: string): Promise<void>;
2
- export declare function tryPublishDestroy(item: any, destroyOutput: string): Promise<void>;
3
- export declare function publishApply(item: any, applyOutput: string, kind: string): Promise<void>;
1
+ export declare function tryPublishApply(item: any, planOutput: string, kind: string, isSuccess?: boolean): Promise<void>;
2
+ export declare function tryPublishDestroy(item: any, destroyOutput: string, isSuccess?: boolean): Promise<void>;
3
+ export declare function publishApply(item: any, applyOutput: string, kind: string, isSuccess?: boolean): Promise<void>;
4
4
  export declare function tryCreateErrorSummary(title: string, errorMsg: string): string;
5
5
  export declare function extractPrInfo(item: any, annotation?: 'firestartr.dev/last-state-pr' | 'firestartr.dev/pull-request-plan'): {
6
6
  prNumber: number;
@@ -9,4 +9,4 @@ export declare function extractPrInfo(item: any, annotation?: 'firestartr.dev/la
9
9
  };
10
10
  export declare function tryPublishError(item: any, reason: string, message: string): Promise<void>;
11
11
  export declare function publishError(item: any, reason: string, message: string): Promise<void>;
12
- export declare function publishPlan(item: any, planOutput: string, prNumber: number, repo: string, org: string): Promise<void>;
12
+ export declare function publishPlan(item: any, planOutput: string, prNumber: number, repo: string, org: string, isSuccess?: boolean): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestartr/cli",
3
- "version": "1.54.0",
3
+ "version": "1.55.0-snapshot-1",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",