@firestartr/cli 1.54.0-snapshot-1 → 1.54.0-snapshot-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/build/index.js +390 -511
  2. package/build/packages/cdk8s_renderer/imports/firestartr.dev.d.ts +7 -1
  3. package/build/packages/cdk8s_renderer/src/claims/base/schemas/common-meta.schema.d.ts +0 -6
  4. package/build/packages/cdk8s_renderer/src/claims/base/schemas/index.d.ts +60 -97
  5. package/build/packages/cdk8s_renderer/src/claims/external-secrets/external-secrets.schema.d.ts +18 -20
  6. package/build/packages/cdk8s_renderer/src/claims/external-secrets/index.d.ts +18 -20
  7. package/build/packages/cdk8s_renderer/src/claims/github/component.schema.d.ts +8 -6
  8. package/build/packages/cdk8s_renderer/src/claims/github/group.schema.d.ts +0 -6
  9. package/build/packages/cdk8s_renderer/src/claims/github/index.d.ts +8 -24
  10. package/build/packages/cdk8s_renderer/src/claims/github/orgwebhook.schema.d.ts +0 -6
  11. package/build/packages/cdk8s_renderer/src/claims/github/repository.d.ts +1 -0
  12. package/build/packages/cdk8s_renderer/src/claims/github/user.schema.d.ts +0 -6
  13. package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/index.d.ts +34 -2
  14. package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/terraform.schema.d.ts +34 -2
  15. package/build/packages/cdk8s_renderer/src/loader/lazy_loader.d.ts +1 -1
  16. package/build/packages/cdk8s_renderer/src/refsSorter/refsExtractor.d.ts +1 -1
  17. package/build/packages/operator/src/metrics/CRStates.d.ts +1 -0
  18. package/build/packages/operator/src/syncCtl.d.ts +1 -0
  19. package/build/packages/operator/src/utils/index.d.ts +0 -7
  20. package/build/packages/operator/src/utils/operationErrorMessages.d.ts +1 -0
  21. package/build/packages/provisioner/src/resources/resource.d.ts +1 -4
  22. package/build/packages/terraform_provisioner/src/resolutor/index.d.ts +1 -0
  23. package/build/packages/terraform_provisioner/src/resolutor/resolver.d.ts +1 -0
  24. package/package.json +1 -1
  25. package/build/packages/cdk8s_renderer/src/claims/base/schemas/sync-config.schema.d.ts +0 -47
package/build/index.js CHANGED
@@ -356807,10 +356807,6 @@ class SyncerInitializer extends InitializerPatches {
356807
356807
  const provider = helperCTX(ctx).provider;
356808
356808
  return claim.providers[provider].sync || {};
356809
356809
  }
356810
- function policyInfo(ctx) {
356811
- const provider = helperCTX(ctx).provider;
356812
- return claim.providers[provider].policy;
356813
- }
356814
356810
  return [
356815
356811
  {
356816
356812
  validate(cr) {
@@ -356829,38 +356825,33 @@ class SyncerInitializer extends InitializerPatches {
356829
356825
  if (!PERIOD_VALIDATOR.test(cr.metadata.annotations['firestartr.dev/sync-period'])) {
356830
356826
  throw `${this.identify()}: period incorrect '${cr.metadata.annotations['firestartr.dev/sync-period']}' for ${cr.kind}/${cr.metadata.name}`;
356831
356827
  }
356828
+ return true;
356832
356829
  }
356833
356830
  else if (helperHasSyncSchedule(cr)) {
356834
356831
  if (!catalog_common.cron.isValidCron(cr.metadata.annotations[SYNC_SCHED_ANNOTATION])) {
356835
356832
  throw `${this.identify()}: sync-schedule: cron incorrect '${cr.metadata.annotations[SYNC_SCHED_ANNOTATION]}' for ${cr.kind}/${cr.metadata.name}`;
356836
356833
  }
356837
356834
  }
356838
- return true;
356835
+ else {
356836
+ return true;
356837
+ }
356839
356838
  },
356840
356839
  apply(cr) {
356841
- cr.metadata.annotations = cr.metadata.annotations || {};
356842
- // Apply general policy annotation
356843
- const policy = policyInfo(this);
356844
- // Default to 'apply' for GitHub resources when no policy is specified
356845
- const provider = helperCTX(this).provider;
356846
- const defaultPolicy = provider === 'github' ? 'apply' : undefined;
356847
- if (policy) {
356848
- cr.metadata.annotations['firestartr.dev/policy'] = policy;
356849
- }
356850
- else if (defaultPolicy) {
356851
- cr.metadata.annotations['firestartr.dev/policy'] = defaultPolicy;
356852
- }
356853
356840
  if (syncInfo(this).enabled) {
356841
+ cr.metadata.annotations = cr.metadata.annotations || {};
356854
356842
  cr.metadata.annotations['firestartr.dev/sync-enabled'] = 'true';
356855
356843
  if (syncInfo(this).period) {
356844
+ cr.metadata.annotations = cr.metadata.annotations || {};
356856
356845
  cr.metadata.annotations['firestartr.dev/sync-period'] =
356857
356846
  syncInfo(this).period;
356858
356847
  }
356859
356848
  if (syncInfo(this).policy) {
356849
+ cr.metadata.annotations = cr.metadata.annotations || {};
356860
356850
  cr.metadata.annotations['firestartr.dev/sync-policy'] =
356861
356851
  syncInfo(this).policy;
356862
356852
  }
356863
356853
  if (syncInfo(this).schedule) {
356854
+ cr.metadata.annotations = cr.metadata.annotations || {};
356864
356855
  cr.metadata.annotations[SYNC_SCHED_ANNOTATION] =
356865
356856
  syncInfo(this).schedule;
356866
356857
  cr.metadata.annotations[SYNC_SCHED_TIMEZONE_ANNOTATION] =
@@ -357054,6 +357045,7 @@ class FirestartrAllClaim {
357054
357045
 
357055
357046
 
357056
357047
 
357048
+
357057
357049
  class RefValuesNormalizer extends Normalizer {
357058
357050
  constructor() {
357059
357051
  super(...arguments);
@@ -357093,6 +357085,14 @@ providerValues, resolveRef, references = new Map()) {
357093
357085
  for (const key in providerValues) {
357094
357086
  values[key] = await interpolateObject(providerValues[key], references, resolveRef);
357095
357087
  }
357088
+ let secretRefCount = 0;
357089
+ for (const key in providerValues) {
357090
+ if (isRepoSecretRef(providerValues[key])) {
357091
+ values[key] = await interpolateSecretClaimRef(providerValues[key], references,
357092
+ // closure to increase the refCount and avoid collision
357093
+ () => secretRefCount++);
357094
+ }
357095
+ }
357096
357096
  return { values, references: Array.from(updatedReferences.values()) };
357097
357097
  }
357098
357098
  async function interpolateObject(toInterpolate, references, resolveRef) {
@@ -357162,6 +357162,40 @@ async function replaceReferencesValues(contents, references, resolveRef) {
357162
357162
  }
357163
357163
  return replacedContent;
357164
357164
  }
357165
+ async function interpolateSecretClaimRef(secretClaimRef, references, getSecretRefCountF) {
357166
+ const extractedSecretClaimRef = {
357167
+ ...extractRepoSecretRef(secretClaimRef),
357168
+ // force the kind to ALWAYS be a Secret
357169
+ kind: 'Secret',
357170
+ };
357171
+ // has already been visited
357172
+ const alreadyPresentKey = findSecretKey(extractedSecretClaimRef, references);
357173
+ if (alreadyPresentKey)
357174
+ return alreadyPresentKey;
357175
+ // new reference we have to build it
357176
+ const secretClaimRefInternalKey = `secret-ref-${getSecretRefCountF()}`;
357177
+ // we set the secret value
357178
+ references.set(secretClaimRefInternalKey, {
357179
+ name: secretClaimRefInternalKey,
357180
+ ref: extractedSecretClaimRef,
357181
+ });
357182
+ return secretClaimRefInternalKey;
357183
+ }
357184
+ function findSecretKey(secretClaimRef, references) {
357185
+ const entry = Array.from(references.entries()).find(([, value]) => {
357186
+ // Destructure the entry to easily access the value.
357187
+ // Check if the value is an object and matches all properties.
357188
+ return (typeof value === 'object' &&
357189
+ value !== null &&
357190
+ value.ref !== null &&
357191
+ typeof value.ref === 'object' &&
357192
+ value.ref.kind === secretClaimRef.kind &&
357193
+ value.ref.name === secretClaimRef.name &&
357194
+ value.ref.key === secretClaimRef.key);
357195
+ });
357196
+ // If a matching entry was found, return its key (the first element of the entry array).
357197
+ return entry ? entry[0] : undefined;
357198
+ }
357165
357199
 
357166
357200
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/normalizers/RevisionNormalizer.ts
357167
357201
 
@@ -357293,14 +357327,20 @@ const kindMap = {
357293
357327
  secret: 'SecretsClaim',
357294
357328
  domain: 'DomainClaim',
357295
357329
  };
357330
+ // this function is intended to search for refs of the same kind
357331
+ // it is used to search for circular references (i.e. a reference to oneself)
357332
+ // to extract all type of references use extractAllRefs
357296
357333
  function extractRefs(renderClaims, kind) {
357297
357334
  const result = {};
357298
357335
  for (const key in renderClaims) {
357299
357336
  const claim = renderClaims[key].claim;
357300
357337
  let refs = [];
357338
+ // for workspaces
357339
+ let [tfWorkspaceRefs, secretsRefs] = [[], []];
357301
357340
  switch (kind) {
357302
357341
  case 'TFWorkspaceClaim':
357303
- refs = getTfWorkspacesRefs(claim.providers.terraform.values);
357342
+ [tfWorkspaceRefs, secretsRefs] = getTfWorkspacesRefs(claim.providers.terraform.values);
357343
+ refs = [...tfWorkspaceRefs];
357304
357344
  break;
357305
357345
  case 'GroupClaim':
357306
357346
  /**
@@ -357324,11 +357364,13 @@ function extractAllRefs(claimData) {
357324
357364
  refs.push(...extractVirtualRefs(parsedClaim));
357325
357365
  switch (parsedClaim.kind) {
357326
357366
  case 'TFWorkspaceClaim': {
357327
- const tfWorkspaceRefs = getTfWorkspacesRefs(parsedClaim.providers.terraform.values);
357367
+ const [tfWorkspaceRefs, secretRefs] = getTfWorkspacesRefs(parsedClaim.providers.terraform.values);
357328
357368
  tfWorkspaceRefs.forEach((ref, idx, arr) => {
357329
357369
  arr[idx] = `TFWorkspaceClaim-${ref}`;
357330
357370
  });
357371
+ cdk8s_renderer_src_logger.debug(`Obtained the following secret refs for ${parsedClaim.kind}/${parsedClaim.name}: ${JSON.stringify(secretRefs)}`);
357331
357372
  refs.push(...tfWorkspaceRefs);
357373
+ refs.push(...secretRefs);
357332
357374
  break;
357333
357375
  }
357334
357376
  case 'GroupClaim': {
@@ -357373,22 +357415,28 @@ function getGroupParentRef(parent, references = []) {
357373
357415
  }
357374
357416
  return references;
357375
357417
  }
357376
- function getTfWorkspacesRefs(values, references = []) {
357418
+ function getTfWorkspacesRefs(values, references = [], secretsRefs = []) {
357377
357419
  const regex = catalog_common.types.regex.TFWorkspaceRefRegex;
357378
357420
  for (const key in values) {
357379
357421
  switch (typeof values[key]) {
357380
357422
  case 'object':
357381
- getTfWorkspacesRefs(values[key], references);
357423
+ getTfWorkspacesRefs(values[key], references, secretsRefs);
357382
357424
  break;
357383
357425
  case 'string':
357426
+ // Extract all implicit refs
357384
357427
  for (const match of values[key].matchAll(regex)) {
357385
357428
  const [_, claimName] = match;
357386
357429
  references.push(claimName);
357387
357430
  }
357431
+ // extract a secretsclaim ref
357432
+ if (isRepoSecretRef(values[key])) {
357433
+ const secretRef = extractRepoSecretRef(values[key]);
357434
+ secretsRefs.push(`SecretsClaim-${secretRef.name}`);
357435
+ }
357388
357436
  break;
357389
357437
  }
357390
357438
  }
357391
- return references;
357439
+ return [references, secretsRefs];
357392
357440
  }
357393
357441
  function getComponentVarsAndSecretsRefs(parsedClaim) {
357394
357442
  const refs = {};
@@ -357581,76 +357629,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
357581
357629
  },
357582
357630
  additionalProperties: false,
357583
357631
  },
357584
- PolicyType: {
357585
- $id: 'firestartr.dev://common/PolicyType',
357586
- type: 'string',
357587
- description: 'Policy for resource management',
357588
- enum: [
357589
- 'apply',
357590
- 'create-only',
357591
- 'create-update-only',
357592
- 'full-control',
357593
- 'observe',
357594
- 'observe-only',
357595
- ],
357596
- },
357597
- },
357598
- });
357599
-
357600
- ;// CONCATENATED MODULE: ../cdk8s_renderer/src/claims/base/schemas/sync-config.schema.ts
357601
- /* harmony default export */ const sync_config_schema = ({
357602
- $id: 'SyncConfig',
357603
- definitions: {
357604
- SyncConfig: {
357605
- $id: 'firestartr.dev://common/SyncConfig',
357606
- type: 'object',
357607
- description: 'Sync configuration for resources',
357608
- properties: {
357609
- enabled: {
357610
- type: 'boolean',
357611
- description: 'Enable periodic sync operations',
357612
- },
357613
- period: {
357614
- type: 'string',
357615
- pattern: '^[0-9]+[smhd]$',
357616
- description: 'Sync period (e.g., 1h, 30m, 5s). Must be enabled without schedule.',
357617
- },
357618
- schedule: {
357619
- type: 'string',
357620
- description: 'Cron schedule for sync operations. Must be enabled without period.',
357621
- },
357622
- schedule_timezone: {
357623
- type: 'string',
357624
- description: 'Timezone for cron schedule (e.g., UTC, America/New_York)',
357625
- },
357626
- policy: {
357627
- type: 'string',
357628
- description: 'Policy for sync operations (apply or observe)',
357629
- },
357630
- },
357631
- additionalProperties: false,
357632
- required: ['enabled'],
357633
- oneOf: [
357634
- {
357635
- required: ['period'],
357636
- },
357637
- {
357638
- required: ['schedule'],
357639
- },
357640
- {
357641
- not: {
357642
- anyOf: [
357643
- {
357644
- required: ['period'],
357645
- },
357646
- {
357647
- required: ['schedule'],
357648
- },
357649
- ],
357650
- },
357651
- },
357652
- ],
357653
- },
357654
357632
  },
357655
357633
  });
357656
357634
 
@@ -358011,9 +357989,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358011
357989
  {
358012
357990
  type: 'object',
358013
357991
  properties: {
358014
- policy: {
358015
- $ref: 'firestartr.dev://common/PolicyType',
358016
- },
358017
357992
  privacy: {
358018
357993
  type: 'string',
358019
357994
  enum: ['closed', 'secret'],
@@ -358024,9 +357999,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358024
357999
  org: {
358025
358000
  type: 'string',
358026
358001
  },
358027
- sync: {
358028
- $ref: 'firestartr.dev://common/SyncConfig',
358029
- },
358030
358002
  },
358031
358003
  required: ['org', 'privacy'],
358032
358004
  },
@@ -358052,9 +358024,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358052
358024
  {
358053
358025
  type: 'object',
358054
358026
  properties: {
358055
- policy: {
358056
- $ref: 'firestartr.dev://common/PolicyType',
358057
- },
358058
358027
  role: {
358059
358028
  type: 'string',
358060
358029
  enum: ['admin', 'member'],
@@ -358062,9 +358031,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358062
358031
  org: {
358063
358032
  type: 'string',
358064
358033
  },
358065
- sync: {
358066
- $ref: 'firestartr.dev://common/SyncConfig',
358067
- },
358068
358034
  },
358069
358035
  required: ['org', 'role'],
358070
358036
  },
@@ -358089,9 +358055,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358089
358055
  {
358090
358056
  type: 'object',
358091
358057
  properties: {
358092
- policy: {
358093
- $ref: 'firestartr.dev://common/PolicyType',
358094
- },
358095
358058
  org: {
358096
358059
  type: 'string',
358097
358060
  description: 'The github organization name',
@@ -358100,9 +358063,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358100
358063
  type: 'string',
358101
358064
  enum: ['private', 'public', 'internal'],
358102
358065
  },
358103
- sync: {
358104
- $ref: 'firestartr.dev://common/SyncConfig',
358105
- },
358106
358066
  features: {
358107
358067
  type: 'array',
358108
358068
  items: {
@@ -358115,6 +358075,14 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358115
358075
  secrets: {
358116
358076
  $ref: 'firestartr.dev://github/GithubComponentClaimSecrets',
358117
358077
  },
358078
+ topics: {
358079
+ type: 'array',
358080
+ items: {
358081
+ type: 'string',
358082
+ maxLength: 50,
358083
+ pattern: '^[a-z0-9][a-z0-9-]*$',
358084
+ },
358085
+ },
358118
358086
  },
358119
358087
  required: ['visibility', 'org'],
358120
358088
  },
@@ -358138,9 +358106,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358138
358106
  {
358139
358107
  type: 'object',
358140
358108
  properties: {
358141
- policy: {
358142
- $ref: 'firestartr.dev://common/PolicyType',
358143
- },
358144
358109
  orgName: {
358145
358110
  type: 'string',
358146
358111
  description: 'Organization name on GitHub',
@@ -358174,9 +358139,6 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358174
358139
  },
358175
358140
  required: ['url', 'contentType', 'events', 'secretRef'],
358176
358141
  },
358177
- sync: {
358178
- $ref: 'firestartr.dev://common/SyncConfig',
358179
- },
358180
358142
  },
358181
358143
  required: ['orgName', 'webhook'],
358182
358144
  },
@@ -358348,7 +358310,15 @@ const GithubSchemas = [
358348
358310
  type: 'object',
358349
358311
  properties: {
358350
358312
  policy: {
358351
- $ref: 'firestartr.dev://common/PolicyType',
358313
+ type: 'string',
358314
+ enum: [
358315
+ 'apply',
358316
+ 'create-only',
358317
+ 'create-update-only',
358318
+ 'full-control',
358319
+ 'observe',
358320
+ 'observe-only',
358321
+ ],
358352
358322
  },
358353
358323
  name: {
358354
358324
  type: 'string',
@@ -358358,7 +358328,47 @@ const GithubSchemas = [
358358
358328
  enum: ['remote', 'inline', 'Remote', 'Inline'],
358359
358329
  },
358360
358330
  sync: {
358361
- $ref: 'firestartr.dev://common/SyncConfig',
358331
+ type: 'object',
358332
+ properties: {
358333
+ enabled: {
358334
+ type: 'boolean',
358335
+ },
358336
+ period: {
358337
+ type: 'string',
358338
+ pattern: '^[0-9]+[smhd]$',
358339
+ },
358340
+ schedule: {
358341
+ type: 'string',
358342
+ },
358343
+ schedule_timezone: {
358344
+ type: 'string',
358345
+ },
358346
+ policy: {
358347
+ type: 'string',
358348
+ },
358349
+ },
358350
+ additionalProperties: false,
358351
+ required: ['enabled'],
358352
+ oneOf: [
358353
+ {
358354
+ required: ['period'],
358355
+ },
358356
+ {
358357
+ required: ['schedule'],
358358
+ },
358359
+ {
358360
+ not: {
358361
+ anyOf: [
358362
+ {
358363
+ required: ['period'],
358364
+ },
358365
+ {
358366
+ required: ['schedule'],
358367
+ },
358368
+ ],
358369
+ },
358370
+ },
358371
+ ],
358362
358372
  },
358363
358373
  valuesSchema: {
358364
358374
  type: 'string',
@@ -358546,7 +358556,11 @@ const ArgoCDSchemas = [argocd_schema];
358546
358556
  additionalProperties: false,
358547
358557
  type: 'object',
358548
358558
  properties: {
358549
- secretName: { type: 'string' },
358559
+ secretName: {
358560
+ type: 'string',
358561
+ description: 'Validation for Kubernetes Secret keys, allowing only alphanumeric characters, hyphens, underscores, and dots.',
358562
+ pattern: '^([a-zA-Z0-9._-]+)$',
358563
+ },
358550
358564
  remoteRef: { type: 'string' },
358551
358565
  },
358552
358566
  required: ['secretName'],
@@ -358609,29 +358623,24 @@ const ArgoCDSchemas = [argocd_schema];
358609
358623
  allOf: [
358610
358624
  { $ref: 'firestartr.dev://common/ClaimProviderEnvelope' },
358611
358625
  {
358612
- anyOf: [
358613
- {
358614
- properties: {
358615
- externalSecrets: {
358616
- $ref: 'firestartr.dev://secrets/ExternalSecretsSection',
358617
- },
358618
- secretStore: {
358619
- $ref: 'firestartr.dev://secrets/SecretStore',
358620
- },
358621
- },
358622
- required: ['secretStore', 'externalSecrets'],
358626
+ type: 'object',
358627
+ properties: {
358628
+ externalSecrets: {
358629
+ $ref: 'firestartr.dev://secrets/ExternalSecretsSection',
358623
358630
  },
358624
- {
358625
- properties: {
358626
- pushSecrets: {
358627
- $ref: 'firestartr.dev://secrets/PushSecretsSection',
358628
- },
358629
- secretStore: {
358630
- $ref: 'firestartr.dev://secrets/SecretStore',
358631
- },
358632
- },
358633
- required: ['secretStore', 'pushSecrets'],
358631
+ secretStore: {
358632
+ $ref: 'firestartr.dev://secrets/SecretStore',
358634
358633
  },
358634
+ pushSecrets: {
358635
+ $ref: 'firestartr.dev://secrets/PushSecretsSection',
358636
+ },
358637
+ },
358638
+ // 1. MANDATORY RULE (ALWAYS): secretStore
358639
+ required: ['secretStore'],
358640
+ // 2. CONDITIONAL RULE (AT LEAST ONE): externalSecrets OR pushSecrets
358641
+ anyOf: [
358642
+ { required: ['externalSecrets'] },
358643
+ { required: ['pushSecrets'] },
358635
358644
  ],
358636
358645
  },
358637
358646
  ],
@@ -358659,12 +358668,10 @@ const SecretsSchemas = [external_secrets_schema];
358659
358668
 
358660
358669
 
358661
358670
 
358662
-
358663
358671
  const schemas = {
358664
358672
  root: root_schema,
358665
358673
  schemas: [
358666
358674
  common_meta_schema,
358667
- sync_config_schema,
358668
358675
  group_schema,
358669
358676
  user_schema,
358670
358677
  component_schema,
@@ -358861,7 +358868,7 @@ function checkGrep() {
358861
358868
  });
358862
358869
  });
358863
358870
  }
358864
- async function loadClaim(claimRef, org, defaults = loadClaimDefaults(), patchClaim = loader_patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, cwd, existingRefs = {}) {
358871
+ async function loadClaim(claimRef, org, defaults = loadClaimDefaults(), patchClaim = loader_patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, cwd, existingRefs = {}, postValidations = new Map()) {
358865
358872
  await checkGrep();
358866
358873
  let result = existingRefs;
358867
358874
  cdk8s_renderer_src_logger.info(`Load reference ${claimRef}`);
@@ -358899,7 +358906,7 @@ async function loadClaim(claimRef, org, defaults = loadClaimDefaults(), patchCla
358899
358906
  const references = extractAllRefs(catalog_common.io.toYaml(claim));
358900
358907
  for (const ref of references) {
358901
358908
  if (!result[ref]) {
358902
- const resolvedReferences = await loadClaim(ref, org, defaults, patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, cwd, result);
358909
+ const [resolvedReferences] = await loadClaim(ref, org, defaults, patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, cwd, result, postValidations);
358903
358910
  result = lodash_default().merge(result, resolvedReferences);
358904
358911
  }
358905
358912
  }
@@ -358907,7 +358914,7 @@ async function loadClaim(claimRef, org, defaults = loadClaimDefaults(), patchCla
358907
358914
  catch (err) {
358908
358915
  throw `Lazy Loading: ${err}`;
358909
358916
  }
358910
- return result;
358917
+ return [result, postValidations];
358911
358918
  }
358912
358919
  let LoadedClaims = {};
358913
358920
  let VisitedClaims = {};
@@ -359309,7 +359316,7 @@ async function loadClaimsList(claimRefList, claimsPath = config_getPath('claims'
359309
359316
  };
359310
359317
  const defaults = loadClaimDefaults();
359311
359318
  for await (const claimRef of claimRefList) {
359312
- const renderedClaimData = await loadClaim(claimRef, getOrg(), defaults, loader_patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, claimsPath);
359319
+ const [renderedClaimData] = await loadClaim(claimRef, getOrg(), defaults, loader_patchClaim, loadInitializers, loadGlobals, loadOverrides, loadNormalizers, claimsPath);
359313
359320
  data.renderClaims = lodash_default().merge(data.renderClaims, renderedClaimData);
359314
359321
  }
359315
359322
  const crClaimReferences = [];
@@ -362202,6 +362209,7 @@ function toJson_FirestartrGithubRepositorySpecRepo(obj) {
362202
362209
  'hasIssues': obj.hasIssues,
362203
362210
  'hasWiki': obj.hasWiki,
362204
362211
  'pages': obj.pages,
362212
+ 'topics': obj.topics?.map(y => y),
362205
362213
  'visibility': obj.visibility,
362206
362214
  'defaultBranch': obj.defaultBranch,
362207
362215
  'additionalBranches': obj.additionalBranches?.map(y => toJson_FirestartrGithubRepositorySpecRepoAdditionalBranches(y)),
@@ -363508,6 +363516,8 @@ var FirestartrTerraformWorkspaceSpecReferencesRefKind;
363508
363516
  FirestartrTerraformWorkspaceSpecReferencesRefKind["FIRESTARTR_TERRAFORM_WORKSPACE"] = "FirestartrTerraformWorkspace";
363509
363517
  /** ExternalSecret */
363510
363518
  FirestartrTerraformWorkspaceSpecReferencesRefKind["EXTERNAL_SECRET"] = "ExternalSecret";
363519
+ /** Secret */
363520
+ FirestartrTerraformWorkspaceSpecReferencesRefKind["SECRET"] = "Secret";
363511
363521
  })(FirestartrTerraformWorkspaceSpecReferencesRefKind || (FirestartrTerraformWorkspaceSpecReferencesRefKind = {}));
363512
363522
  /**
363513
363523
  * @schema FirestartrTerraformWorkspaceSpecContextBackendRefKind
@@ -364149,12 +364159,8 @@ class FeatureRepoChart extends BaseGithubChart {
364149
364159
  const annotations = this.getAnnotationsFromRepo(this.get('repoCr'), [
364150
364160
  'claim-ref',
364151
364161
  'revision',
364152
- 'policy',
364153
- 'sync-policy',
364154
364162
  'sync-enabled',
364155
364163
  'sync-period',
364156
- 'sync-schedule',
364157
- 'sync-schedule-timezone',
364158
364164
  ]);
364159
364165
  cr.metadata.annotations = {
364160
364166
  ...cr.metadata.annotations,
@@ -364229,12 +364235,8 @@ class RepoSecretsSectionChart extends BaseGithubChart {
364229
364235
  const annotations = this.getAnnotationsFromRepo(this.get('repoCr'), [
364230
364236
  'claim-ref',
364231
364237
  'revision',
364232
- 'policy',
364233
- 'sync-policy',
364234
364238
  'sync-enabled',
364235
364239
  'sync-period',
364236
- 'sync-schedule',
364237
- 'sync-schedule-timezone',
364238
364240
  ]);
364239
364241
  cr.metadata.annotations = {
364240
364242
  ...cr.metadata.annotations,
@@ -364333,6 +364335,7 @@ class GithubRepositoryChart extends BaseGithubChart {
364333
364335
  defaultBranch: claim.providers.github?.branchStrategy?.defaultBranch,
364334
364336
  codeowners: createCodeOwnersData(claim),
364335
364337
  additionalBranches: claim.providers.github.additionalBranches || [],
364338
+ topics: claim.providers.github.topics || [],
364336
364339
  },
364337
364340
  actions,
364338
364341
  permissions: this.createPermissions(claim),
@@ -365404,11 +365407,27 @@ async function renderClaim(catalogScope, firestartrScope, claim, patches, previo
365404
365407
  }
365405
365408
 
365406
365409
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/validations/crossReferences.ts
365410
+
365407
365411
  const IS_COMPONENT_CLAIM_REF = new RegExp(/^ComponentClaim-/);
365412
+ const IS_TF_WORKSPACE = new RegExp(/^TFWorkspaceClaim-/);
365408
365413
  function validateSubReferences(renderClaims) {
365409
365414
  for (const ref of Object.keys(renderClaims)) {
365410
365415
  if (IS_COMPONENT_CLAIM_REF.test(ref))
365411
365416
  validateClaimsSecretsRefs(ref, renderClaims);
365417
+ else if (IS_TF_WORKSPACE.test(ref))
365418
+ validateTFClaimsSecretsRefs(ref, renderClaims);
365419
+ }
365420
+ }
365421
+ function validateTFClaimsSecretsRefs(ref, renderClaims) {
365422
+ const claim = renderClaims[ref].claim;
365423
+ const values = claim.providers?.terraform?.values;
365424
+ const secretRefs = Object.values(values).filter((v) => isRepoSecretRef(v));
365425
+ for (const secret of secretRefs) {
365426
+ const [secretName, key] = secret.split(':').slice(2);
365427
+ const keyFound = searchSecretKey(renderClaims[`SecretsClaim-${secretName}`].claim, key);
365428
+ if (!keyFound) {
365429
+ throw new Error(`CrossReference error: TFWorkspaceClaim/${claim.name} references a non-existent secret key: '${secretName}:${key}'`);
365430
+ }
365412
365431
  }
365413
365432
  }
365414
365433
  function validateClaimsSecretsRefs(ref, renderClaims) {
@@ -367785,12 +367804,19 @@ function updateConditionByType(conditionList, type, newCondition) {
367785
367804
  return conditionList;
367786
367805
  }
367787
367806
 
367807
+ ;// CONCATENATED MODULE: ../operator/src/utils/operationErrorMessages.ts
367808
+ const APPLY_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform apply operation.';
367809
+ const DESTROY_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform destroy operation.';
367810
+ const PLAN_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform plan operation.';
367811
+ const SYNC_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Sync operation.';
367812
+
367788
367813
  ;// CONCATENATED MODULE: ../operator/src/syncCtl.ts
367789
367814
  // Machinery for syncing
367790
367815
 
367791
367816
 
367792
367817
 
367793
367818
 
367819
+
367794
367820
  const DEFAULT_REVISION_TIME = '1m';
367795
367821
  async function createWatcherForItem(itemPath, itemCR) {
367796
367822
  const item = itemCR ?? (await getItemByItemPath(itemPath));
@@ -367853,7 +367879,7 @@ async function getSyncStatus(itemPath, itemCR) {
367853
367879
  : (await getSyncSpecs(itemPath, item)).schedule
367854
367880
  ? 'Scheduled'
367855
367881
  : 'Period';
367856
- return {
367882
+ const syncStatus = {
367857
367883
  itemPath,
367858
367884
  syncMode: mode,
367859
367885
  conditions: [syncCondition],
@@ -367861,6 +367887,11 @@ async function getSyncStatus(itemPath, itemCR) {
367861
367887
  nextTimeoutInMS: isLapsed ? -1 : nextSyncDate.getTime() - Date.now(),
367862
367888
  intervalLapsed: isLapsed,
367863
367889
  };
367890
+ if (syncCondition) {
367891
+ syncStatus.hasSyncFailed =
367892
+ syncCondition.message === SYNC_DEFAULT_ERROR_MESSAGE;
367893
+ }
367894
+ return syncStatus;
367864
367895
  }
367865
367896
  }
367866
367897
  async function setSyncStatus(itemPath, reason, status, message) {
@@ -368509,6 +368540,15 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
368509
368540
  yield transition;
368510
368541
  }
368511
368542
  if (needsUpdateSyncConditions) {
368543
+ if (operation === OperationType.SYNC) {
368544
+ // let's check if the process has not failed
368545
+ const syncStatus = await getSyncStatus(workItem.handler.itemPath());
368546
+ if (syncStatus.hasSyncFailed) {
368547
+ // we do not update sync because we are not going to trigger
368548
+ // a RETRY operation if the sync has failed
368549
+ return;
368550
+ }
368551
+ }
368512
368552
  await setSyncStatus(workItem.handler.itemPath(), operation, operation === OperationType.SYNC ? 'True' : 'False', 'Sync process finished');
368513
368553
  void syncCtl.updateItem(informer_itemPath(pluralKind, item));
368514
368554
  }
@@ -369529,9 +369569,7 @@ function provisionFeatureFiles(scope, feature) {
369529
369569
  ? { ignoreChanges: ['content'] }
369530
369570
  : {};
369531
369571
  const repoConfig = {
369532
- branch: file.targetBranch.length === 0
369533
- ? defaultBranchName
369534
- : file.targetBranch,
369572
+ branch: file.targetBranch || defaultBranchName,
369535
369573
  commitMessage: `feat: ${feature.spec.type} ${feature.spec.version}`,
369536
369574
  content: cdktf_lib.Fn.base64decode(file.content),
369537
369575
  file: file.path,
@@ -370532,15 +370570,10 @@ class Resource {
370532
370570
  this.set('operation', operation);
370533
370571
  this.set('deps', deps);
370534
370572
  }
370535
- async run(options) {
370573
+ async run() {
370536
370574
  await this.preprocess();
370537
370575
  await this.synth();
370538
- if (options?.planOnly) {
370539
- await this.runTerraformPlanOnly();
370540
- }
370541
- else {
370542
- await this.runTerraform();
370543
- }
370576
+ await this.runTerraform();
370544
370577
  await this.postprocess();
370545
370578
  if (this.logStream) {
370546
370579
  this.logStream.end();
@@ -370565,13 +370598,6 @@ class Resource {
370565
370598
  log(msg) {
370566
370599
  this.logFn(msg);
370567
370600
  }
370568
- async runTerraformPlanOnly() {
370569
- await this.onTFStreaming();
370570
- let output = '';
370571
- output += await terraformInit(this.get('main_artifact'), this.logStream);
370572
- output += await terraformPlan(this.get('main_artifact'), this.logStream);
370573
- this.set('output', output);
370574
- }
370575
370601
  async runTerraform() {
370576
370602
  await this.onTFStreaming();
370577
370603
  let output = '';
@@ -370959,7 +370985,7 @@ async function runProvisioner(data, opts) {
370959
370985
  if ('logStreamCallbacksTF' in opts) {
370960
370986
  resource.setTFStreamLogs(opts['logStreamCallbacksTF']);
370961
370987
  }
370962
- await resource.run({ planOnly: opts.planOnly });
370988
+ await resource.run();
370963
370989
  return resource;
370964
370990
  }
370965
370991
  function createInstanceOf(entity, op, deps) {
@@ -371241,57 +371267,6 @@ function helperCreateCheckRunName(cmd, item) {
371241
371267
  return `${item.kind} - ${cmd}`;
371242
371268
  }
371243
371269
 
371244
- ;// CONCATENATED MODULE: ../operator/src/utils/index.ts
371245
- const secretRegex = /\$\{\{ secrets\.(.*?) \}\}/g;
371246
- function replaceConfigSecrets(config, secrets) {
371247
- for (const key in config) {
371248
- if (typeof config[key] === 'object' && config[key] !== null) {
371249
- // If the property is an object, call this function recursively
371250
- replaceConfigSecrets(config[key], secrets);
371251
- }
371252
- else if (typeof config[key] === 'string') {
371253
- // If the property is a string and its value is equal to secrets.something,
371254
- // replace the value with the value of the 'something' key in the secrets object
371255
- config[key] = config[key].replace(secretRegex, (_, group1) => {
371256
- if (!secrets[group1]) {
371257
- throw new Error(`Secret ${group1} not found in secrets`);
371258
- }
371259
- return secrets[group1];
371260
- });
371261
- }
371262
- }
371263
- return config;
371264
- }
371265
- function replaceInlineSecrets(inline, secrets) {
371266
- if (typeof inline !== 'string' || !inline)
371267
- return inline;
371268
- let result = inline;
371269
- result = result.replace(secretRegex, (_, group1) => {
371270
- if (!secrets[group1]) {
371271
- throw new Error(`Secret ${group1} not found in secrets`);
371272
- }
371273
- return secrets[group1];
371274
- });
371275
- return result;
371276
- }
371277
- /**
371278
- * Retrieves a policy annotation value from a custom resource
371279
- * @param item - The CR to get the policy from
371280
- * @param annotation - The annotation key to retrieve
371281
- * @returns The policy value, or undefined if not set
371282
- */
371283
- function getPolicy(item, annotation) {
371284
- const policy = item.metadata.annotations && item.metadata.annotations[annotation];
371285
- if (policy)
371286
- return policy;
371287
- return undefined;
371288
- }
371289
-
371290
- ;// CONCATENATED MODULE: ../operator/src/utils/operationErrorMessages.ts
371291
- const APPLY_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform apply operation.';
371292
- const DESTROY_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform destroy operation.';
371293
- const PLAN_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraform plan operation.';
371294
-
371295
371270
  ;// CONCATENATED MODULE: ../operator/cdktf.ts
371296
371271
 
371297
371272
 
@@ -371302,17 +371277,9 @@ const PLAN_DEFAULT_ERROR_MESSAGE = 'An error occurred while executing the Terraf
371302
371277
 
371303
371278
 
371304
371279
 
371305
- const cdktf_LAST_STATE_PR_ANNOTATION = 'firestartr.dev/last-state-pr';
371306
-
371307
371280
  function processOperation(item, op, handler) {
371308
371281
  operator_src_logger.info(`Processing operation ${op} on ${item.kind}/${item.metadata?.name}`);
371309
371282
  try {
371310
- const policy = getPolicy(item, 'firestartr.dev/policy');
371311
- // If general policy is observe/observe-only, route to observe mode instead of apply
371312
- if (!policy || policy === 'observe' || policy === 'observe-only') {
371313
- operator_src_logger.info(`Policy is '${policy || 'not set (default)'}', routing to observe mode`);
371314
- return cdktf_observe(item, op, handler);
371315
- }
371316
371283
  switch (op) {
371317
371284
  case OperationType.UPDATED:
371318
371285
  return updated(item, op, handler);
@@ -371337,11 +371304,6 @@ function processOperation(item, op, handler) {
371337
371304
  throw e;
371338
371305
  }
371339
371306
  }
371340
- async function* cdktf_observe(item, op, handler) {
371341
- for await (const transition of doPlan(item, op, handler)) {
371342
- yield transition;
371343
- }
371344
- }
371345
371307
  async function* created(item, op, handler) {
371346
371308
  for await (const transition of doApply(item, op, handler)) {
371347
371309
  yield transition;
@@ -371377,18 +371339,8 @@ async function* sync(item, op, handler) {
371377
371339
  status: 'False',
371378
371340
  message: 'Synth CDKTF',
371379
371341
  };
371380
- const syncPolicy = getPolicy(item, 'firestartr.dev/sync-policy');
371381
- if (syncPolicy === 'apply') {
371382
- operator_src_logger.info(`SYNC OPERATION: applying item ${item.metadata.name} with sync-policy=${syncPolicy}`);
371383
- for await (const transition of doApply(item, op, handler)) {
371384
- yield transition;
371385
- }
371386
- }
371387
- else {
371388
- operator_src_logger.info(`SYNC OPERATION: planning item ${item.metadata.name} with sync-policy=${syncPolicy || 'default (observe)'}`);
371389
- for await (const transition of doPlan(item, op, handler)) {
371390
- yield transition;
371391
- }
371342
+ for await (const transition of doApply(item, op, handler)) {
371343
+ yield transition;
371392
371344
  }
371393
371345
  yield {
371394
371346
  item,
@@ -371428,14 +371380,15 @@ async function* markedToDeletion(item, op, handler) {
371428
371380
  message: 'Destroying process started',
371429
371381
  };
371430
371382
  const deps = await handler.resolveReferences();
371431
- const statePr = item?.metadata?.annotations?.[cdktf_LAST_STATE_PR_ANNOTATION];
371383
+ const annotation = 'firestartr.dev/last-state-pr';
371384
+ const statePr = item?.metadata?.annotations?.[annotation];
371432
371385
  const hasStatePr = typeof statePr === 'string' && statePr.trim().length > 0;
371433
371386
  if (!hasStatePr) {
371434
371387
  operator_src_logger.warn(`CR ${item?.kind ?? 'UnknownKind'}/${item?.metadata?.name ?? 'unknown'} ` +
371435
- `has no "${cdktf_LAST_STATE_PR_ANNOTATION}" annotation; skipping GitHub Check Runs (synth, terraform apply).`);
371388
+ `has no "${annotation}" annotation; skipping GitHub Check Runs (synth, terraform apply).`);
371436
371389
  }
371437
371390
  else {
371438
- operator_src_logger.debug(`CR ${item.kind}/${item.metadata.name} uses "${cdktf_LAST_STATE_PR_ANNOTATION}" = ${statePr}`);
371391
+ operator_src_logger.debug(`CR ${item.kind}/${item.metadata.name} uses "${annotation}" = ${statePr}`);
371439
371392
  }
371440
371393
  const destroyOutput = await provisioner.runProvisioner({
371441
371394
  mainCr: item,
@@ -371470,7 +371423,7 @@ async function* markedToDeletion(item, op, handler) {
371470
371423
  };
371471
371424
  await handler.finalize(handler.pluralKind, item.metadata.namespace, item, 'firestartr.dev/finalizer');
371472
371425
  await handler.writeTerraformOutputInTfResult(item, output);
371473
- if (item.metadata.annotations[cdktf_LAST_STATE_PR_ANNOTATION] || false) {
371426
+ if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
371474
371427
  await addDestroyCommitStatus(item, 'success', 'Destroy operation completed', `Terraform Destroy ${item.metadata.name}`);
371475
371428
  }
371476
371429
  void handler.success();
@@ -371557,14 +371510,15 @@ async function* doApply(item, op, handler) {
371557
371510
  }
371558
371511
  const deps = await handler.resolveReferences();
371559
371512
  operator_src_logger.info(`Item ${item.metadata.name} has the following dependencies: ${deps}`);
371560
- const statePr = item?.metadata?.annotations?.[cdktf_LAST_STATE_PR_ANNOTATION];
371513
+ const annotation = 'firestartr.dev/last-state-pr';
371514
+ const statePr = item?.metadata?.annotations?.[annotation];
371561
371515
  const hasStatePr = typeof statePr === 'string' && statePr.trim().length > 0;
371562
371516
  if (!hasStatePr) {
371563
371517
  operator_src_logger.warn(`CR ${item?.kind ?? 'UnknownKind'}/${item?.metadata?.name ?? 'unknown'} ` +
371564
- `has no "${cdktf_LAST_STATE_PR_ANNOTATION}" annotation; skipping GitHub Check Runs (synth, terraform apply).`);
371518
+ `has no "${annotation}" annotation; skipping GitHub Check Runs (synth, terraform apply).`);
371565
371519
  }
371566
371520
  else {
371567
- operator_src_logger.debug(`CR ${item.kind}/${item.metadata.name} uses "${cdktf_LAST_STATE_PR_ANNOTATION}" = ${statePr}`);
371521
+ operator_src_logger.debug(`CR ${item.kind}/${item.metadata.name} uses "${annotation}" = ${statePr}`);
371568
371522
  }
371569
371523
  const applyOutput = await provisioner.runProvisioner({
371570
371524
  mainCr: item,
@@ -371665,220 +371619,6 @@ async function* doApply(item, op, handler) {
371665
371619
  }
371666
371620
  }
371667
371621
  }
371668
- async function* doPlan(item, op, handler) {
371669
- let checkRunCtl;
371670
- try {
371671
- cleanTerraformState();
371672
- yield {
371673
- item,
371674
- reason: op,
371675
- type: 'PLANNING',
371676
- status: 'True',
371677
- message: 'Planning process started',
371678
- };
371679
- const deps = await handler.resolveReferences();
371680
- const statePr = item?.metadata?.annotations?.[cdktf_LAST_STATE_PR_ANNOTATION];
371681
- const hasStatePr = typeof statePr === 'string' && statePr.trim().length > 0;
371682
- if (!hasStatePr) {
371683
- operator_src_logger.warn(`CR ${item?.kind ?? 'UnknownKind'}/${item?.metadata?.name ?? 'unknown'} ` +
371684
- `has no "${cdktf_LAST_STATE_PR_ANNOTATION}" annotation; skipping GitHub Check Runs for plan.`);
371685
- }
371686
- else {
371687
- operator_src_logger.debug(`CR ${item.kind}/${item.metadata.name} uses "${cdktf_LAST_STATE_PR_ANNOTATION}" = ${statePr}`);
371688
- await addPlanStatusCheck(statePr, 'CDKTF plan in progress...');
371689
- }
371690
- // Run provisioner in plan-only mode
371691
- const planResult = await provisioner.runProvisioner({ mainCr: item, deps }, {
371692
- planOnly: true,
371693
- delete: 'deletionTimestamp' in item.metadata,
371694
- ...(hasStatePr
371695
- ? {
371696
- logStreamCallbacksCDKTF: {
371697
- prepare: async () => {
371698
- checkRunCtl = await GHCheckRun('synth', item);
371699
- return checkRunCtl;
371700
- },
371701
- },
371702
- logStreamCallbacksTF: {
371703
- prepare: async () => {
371704
- checkRunCtl = await GHCheckRun('plan', item);
371705
- return checkRunCtl;
371706
- },
371707
- },
371708
- }
371709
- : {}),
371710
- });
371711
- const planOutput = planResult?.output || '';
371712
- // Parse terraform plan output to detect changes
371713
- // Handles multiple Terraform output formats and versions
371714
- const hasChanges = detectPlanChanges(planOutput);
371715
- if (hasChanges) {
371716
- yield {
371717
- item,
371718
- reason: op,
371719
- type: 'OUT_OF_SYNC',
371720
- status: 'True',
371721
- message: 'Plan has changes',
371722
- };
371723
- yield {
371724
- item,
371725
- reason: op,
371726
- type: 'PROVISIONED',
371727
- status: 'False',
371728
- message: 'Plan has changes',
371729
- };
371730
- }
371731
- else {
371732
- yield {
371733
- item,
371734
- reason: op,
371735
- type: 'OUT_OF_SYNC',
371736
- status: 'False',
371737
- message: 'Plan has no changes',
371738
- };
371739
- yield {
371740
- item,
371741
- reason: op,
371742
- type: 'PROVISIONED',
371743
- status: 'True',
371744
- message: 'Plan has no changes',
371745
- };
371746
- }
371747
- // Store plan details for later reference
371748
- yield {
371749
- item,
371750
- reason: op,
371751
- type: 'LAST_PLAN_DETAILS',
371752
- status: 'Unknown',
371753
- message: planOutput,
371754
- };
371755
- yield {
371756
- item,
371757
- reason: op,
371758
- type: 'PLANNING',
371759
- status: 'False',
371760
- message: 'Planning process finished',
371761
- };
371762
- if (hasStatePr) {
371763
- await addPlanStatusCheck(statePr, hasChanges ? 'Plan has changes' : 'Plan has no changes', 'completed');
371764
- }
371765
- }
371766
- catch (e) {
371767
- operator_src_logger.error(`CDKTF plan failed: ${e}`);
371768
- if (checkRunCtl) {
371769
- checkRunCtl.fnOnError(e);
371770
- }
371771
- yield {
371772
- item,
371773
- reason: op,
371774
- type: 'ERROR',
371775
- status: 'True',
371776
- message: PLAN_DEFAULT_ERROR_MESSAGE,
371777
- };
371778
- yield {
371779
- item,
371780
- reason: op,
371781
- type: 'PLANNING',
371782
- status: 'False',
371783
- message: PLAN_DEFAULT_ERROR_MESSAGE,
371784
- };
371785
- yield {
371786
- item,
371787
- reason: op,
371788
- type: 'PROVISIONED',
371789
- status: 'False',
371790
- message: PLAN_DEFAULT_ERROR_MESSAGE,
371791
- };
371792
- const statePr = item?.metadata?.annotations?.[cdktf_LAST_STATE_PR_ANNOTATION];
371793
- if (statePr) {
371794
- const summaryText = tryCreateErrorSummary('CDKTF Plan failed', e);
371795
- await addPlanStatusCheck(statePr, summaryText, 'completed', true);
371796
- }
371797
- await handler.writeTerraformOutputInTfResult(item, e);
371798
- void handler.error();
371799
- }
371800
- }
371801
- /**
371802
- * Detects if a Terraform plan output contains changes
371803
- * Handles multiple Terraform versions and output formats
371804
- * @param planOutput - The text output from terraform plan
371805
- * @returns true if changes are detected, false otherwise
371806
- */
371807
- function detectPlanChanges(planOutput) {
371808
- if (!planOutput || planOutput.trim().length === 0) {
371809
- return false;
371810
- }
371811
- // Pattern 1: "Plan: X to add, Y to change, Z to destroy"
371812
- // Matches: "Plan: 1 to add, 0 to change, 0 to destroy"
371813
- const planPattern = /plan:\s*(\d+)\s+to\s+add,\s*(\d+)\s+to\s+change,\s*(\d+)\s+to\s+destroy/i;
371814
- const planMatch = planOutput.match(planPattern);
371815
- if (planMatch) {
371816
- const add = Number(planMatch[1]);
371817
- const change = Number(planMatch[2]);
371818
- const destroy = Number(planMatch[3]);
371819
- if (add > 0 || change > 0 || destroy > 0) {
371820
- return true;
371821
- }
371822
- // Explicitly found "Plan:" with 0/0/0 - no changes
371823
- return false;
371824
- }
371825
- // Pattern 2: Individual change indicators
371826
- // Handles variations like "1 to add", "2 to change", "3 to destroy"
371827
- const hasAdditions = /\d+\s+to\s+add/i.test(planOutput);
371828
- const hasChanges = /\d+\s+to\s+change/i.test(planOutput);
371829
- const hasDestructions = /\d+\s+to\s+destroy/i.test(planOutput);
371830
- const hasImports = /\d+\s+to\s+import/i.test(planOutput);
371831
- if (hasAdditions || hasChanges || hasDestructions || hasImports) {
371832
- return true;
371833
- }
371834
- // Pattern 3: Resource-level change indicators
371835
- // Matches: "# resource will be created", "# resource will be updated", etc.
371836
- const resourceChangePatterns = [
371837
- /will\s+be\s+(created|destroyed|updated|replaced)/i,
371838
- /must\s+be\s+(created|destroyed|updated|replaced)/i,
371839
- /#.*\s+(create|destroy|update|replace)/i,
371840
- ];
371841
- for (const pattern of resourceChangePatterns) {
371842
- if (pattern.test(planOutput)) {
371843
- return true;
371844
- }
371845
- }
371846
- // Pattern 4: Action symbols in plan output
371847
- // Terraform uses symbols like +, -, ~, -/+ to indicate changes
371848
- const actionSymbols = [
371849
- /^\s*[+]\s+/m,
371850
- /^\s*[-]\s+/m,
371851
- /^\s*[~]\s+/m,
371852
- /^\s*[-][/][+]\s+/m, // Replace
371853
- ];
371854
- for (const pattern of actionSymbols) {
371855
- if (pattern.test(planOutput)) {
371856
- return true;
371857
- }
371858
- }
371859
- // Pattern 5: No changes messages (inverse check)
371860
- const noChangesPatterns = [
371861
- /no\s+changes/i,
371862
- /infrastructure\s+is\s+up[-\s]to[-\s]date/i,
371863
- /your\s+infrastructure\s+matches\s+the\s+configuration/i,
371864
- /0\s+to\s+add,\s*0\s+to\s+change,\s*0\s+to\s+destroy/i,
371865
- ];
371866
- for (const pattern of noChangesPatterns) {
371867
- if (pattern.test(planOutput)) {
371868
- return false;
371869
- }
371870
- }
371871
- // If we find "Plan:" keyword but couldn't parse it, log a warning and err on the side of caution
371872
- if (planOutput.toLowerCase().includes('plan:')) {
371873
- operator_src_logger.warn('Found "Plan:" in output but could not parse change counts. ' +
371874
- 'Raw output excerpt (first 500 chars):\n' +
371875
- planOutput.slice(0, 500) +
371876
- '\nErring on the side of caution and assuming changes.');
371877
- return true;
371878
- }
371879
- // Default: assume no changes if we can't detect any
371880
- return false;
371881
- }
371882
371622
  function cleanTerraformState() {
371883
371623
  external_fs_.rmSync('/library/packages/provisioner/cdktf.out', {
371884
371624
  recursive: true,
@@ -372299,6 +372039,8 @@ ${this.mainBlock}
372299
372039
  }
372300
372040
 
372301
372041
  ;// CONCATENATED MODULE: ../terraform_provisioner/src/resolutor/resolver.ts
372042
+
372043
+ const REG_IS_CLAIM_SECRET_REF = new RegExp(/^secret-ref-\d+$/);
372302
372044
  function resolveString(value, refs) {
372303
372045
  const regex = new RegExp(/(\$\{\{\s*references\.[\w\-.]+\s*\}\})/);
372304
372046
  if (hasRefs(value, regex) > 0) {
@@ -372352,6 +372094,18 @@ function getRefNameFromKey(key) {
372352
372094
  // name is in the first matching group
372353
372095
  return match[1];
372354
372096
  }
372097
+ function resolveClaimSecret(value, refs) {
372098
+ if (typeof value === 'string' && REG_IS_CLAIM_SECRET_REF.test(value)) {
372099
+ if (!Object.prototype.hasOwnProperty.call(refs, value)) {
372100
+ terraform_provisioner_src_logger.error(`SecretsClaim ref ${value} is not present on references`);
372101
+ throw new Error(`SecretsClaim ref ${value} is not present on references`);
372102
+ }
372103
+ return refs[value];
372104
+ }
372105
+ else {
372106
+ return value;
372107
+ }
372108
+ }
372355
372109
  function resolveRef(key, references, wantsInterpolation = false) {
372356
372110
  const refName = getRefNameFromKey(key);
372357
372111
  // check if key exists
@@ -372400,6 +372154,9 @@ function walkList(list, resolveScalar) {
372400
372154
  function resolveValues(values, refs) {
372401
372155
  return walker_walk(values, (value) => resolveScalar(value, refs));
372402
372156
  }
372157
+ function resolveClaimSecrets(values, refs) {
372158
+ return walker_walk(values, (value) => resolveClaimSecret(value, refs));
372159
+ }
372403
372160
 
372404
372161
  ;// CONCATENATED MODULE: ../terraform_provisioner/src/writer_tfvars_json.ts
372405
372162
 
@@ -372411,7 +372168,9 @@ class WriterTfVarsJson extends writer {
372411
372168
  this.references = references;
372412
372169
  }
372413
372170
  __replaceReferences(values, references) {
372414
- return resolveValues(values, references);
372171
+ values = resolveValues(values, references);
372172
+ values = resolveClaimSecrets(values, references);
372173
+ return values;
372415
372174
  }
372416
372175
  __resolveDeps() {
372417
372176
  const replaced = this.__replaceReferences(this.values, this.references);
@@ -372878,6 +372637,40 @@ function tf_checkrun_helperCreateCheckRunName(cmd) {
372878
372637
  return `TFWorkspace - ${cmd}`;
372879
372638
  }
372880
372639
 
372640
+ ;// CONCATENATED MODULE: ../operator/src/utils/index.ts
372641
+ const secretRegex = /\$\{\{ secrets\.(.*?) \}\}/g;
372642
+ function replaceConfigSecrets(config, secrets) {
372643
+ for (const key in config) {
372644
+ if (typeof config[key] === 'object' && config[key] !== null) {
372645
+ // If the property is an object, call this function recursively
372646
+ replaceConfigSecrets(config[key], secrets);
372647
+ }
372648
+ else if (typeof config[key] === 'string') {
372649
+ // If the property is a string and its value is equal to secrets.something,
372650
+ // replace the value with the value of the 'something' key in the secrets object
372651
+ config[key] = config[key].replace(secretRegex, (_, group1) => {
372652
+ if (!secrets[group1]) {
372653
+ throw new Error(`Secret ${group1} not found in secrets`);
372654
+ }
372655
+ return secrets[group1];
372656
+ });
372657
+ }
372658
+ }
372659
+ return config;
372660
+ }
372661
+ function replaceInlineSecrets(inline, secrets) {
372662
+ if (typeof inline !== 'string' || !inline)
372663
+ return inline;
372664
+ let result = inline;
372665
+ result = result.replace(secretRegex, (_, group1) => {
372666
+ if (!secrets[group1]) {
372667
+ throw new Error(`Secret ${group1} not found in secrets`);
372668
+ }
372669
+ return secrets[group1];
372670
+ });
372671
+ return result;
372672
+ }
372673
+
372881
372674
  ;// CONCATENATED MODULE: ../operator/src/tfworkspaces/process-operation.ts
372882
372675
 
372883
372676
 
@@ -372933,7 +372726,7 @@ async function* process_operation_observe(item, op, handler) {
372933
372726
  yield transition;
372934
372727
  }
372935
372728
  }
372936
- async function* doPlanJSONFormat(item, op, handler) {
372729
+ async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) { }) {
372937
372730
  let error = false;
372938
372731
  try {
372939
372732
  yield {
@@ -373034,34 +372827,83 @@ async function* doPlanJSONFormat(item, op, handler) {
373034
372827
  }
373035
372828
  finally {
373036
372829
  if (error) {
373037
- yield {
373038
- item,
373039
- reason: op,
373040
- type: 'PROVISIONED',
373041
- status: 'False',
373042
- message: PLAN_DEFAULT_ERROR_MESSAGE,
373043
- };
373044
- yield {
373045
- item,
373046
- reason: op,
373047
- type: 'PLANNING',
373048
- status: 'False',
373049
- message: PLAN_DEFAULT_ERROR_MESSAGE,
373050
- };
373051
- yield {
373052
- item,
373053
- reason: op,
373054
- type: 'OUT_OF_SYNC',
373055
- status: 'False',
373056
- message: PLAN_DEFAULT_ERROR_MESSAGE,
373057
- };
373058
- yield {
373059
- item,
373060
- reason: op,
373061
- type: 'ERROR',
373062
- status: 'True',
373063
- message: PLAN_DEFAULT_ERROR_MESSAGE,
373064
- };
372830
+ if (op === OperationType.SYNC) {
372831
+ // if there is an error on a sync we never put the state on error
372832
+ // it would be problematic because the RETRY op kicks in
372833
+ if (error) {
372834
+ yield {
372835
+ item,
372836
+ reason: op,
372837
+ type: 'SYNCHRONIZED',
372838
+ status: 'True',
372839
+ message: SYNC_DEFAULT_ERROR_MESSAGE,
372840
+ };
372841
+ yield {
372842
+ item,
372843
+ reason: op,
372844
+ type: 'PROVISIONED',
372845
+ status: 'True',
372846
+ message: 'doPlanJSONFormat',
372847
+ };
372848
+ yield {
372849
+ item,
372850
+ reason: op,
372851
+ type: 'PLANNING',
372852
+ status: 'False',
372853
+ message: 'doPlanJSONFormat',
372854
+ };
372855
+ yield {
372856
+ item,
372857
+ reason: op,
372858
+ type: 'OUT_OF_SYNC',
372859
+ status: 'False',
372860
+ message: 'doPlanJSONFormat',
372861
+ };
372862
+ yield {
372863
+ item,
372864
+ reason: op,
372865
+ type: 'ERROR',
372866
+ status: 'False',
372867
+ message: 'doPlanJSONFormat',
372868
+ };
372869
+ }
372870
+ setResult('SYNC_ERROR_PLAN');
372871
+ }
372872
+ else {
372873
+ yield {
372874
+ item,
372875
+ reason: op,
372876
+ type: 'PROVISIONED',
372877
+ status: 'False',
372878
+ message: PLAN_DEFAULT_ERROR_MESSAGE,
372879
+ };
372880
+ yield {
372881
+ item,
372882
+ reason: op,
372883
+ type: 'PLANNING',
372884
+ status: 'False',
372885
+ message: PLAN_DEFAULT_ERROR_MESSAGE,
372886
+ };
372887
+ yield {
372888
+ item,
372889
+ reason: op,
372890
+ type: 'OUT_OF_SYNC',
372891
+ status: 'False',
372892
+ message: PLAN_DEFAULT_ERROR_MESSAGE,
372893
+ };
372894
+ yield {
372895
+ item,
372896
+ reason: op,
372897
+ type: 'ERROR',
372898
+ status: 'True',
372899
+ message: PLAN_DEFAULT_ERROR_MESSAGE,
372900
+ };
372901
+ }
372902
+ }
372903
+ else {
372904
+ if (op === OperationType.SYNC) {
372905
+ setResult('SYNC_SUCCESS');
372906
+ }
373065
372907
  }
373066
372908
  }
373067
372909
  }
@@ -373075,6 +372917,11 @@ async function* process_operation_renamed(item, op, handler) {
373075
372917
  yield transition;
373076
372918
  }
373077
372919
  }
372920
+ function getPolicy(item, annotation) {
372921
+ const policy = item.metadata.annotations && item.metadata.annotations[annotation];
372922
+ if (policy)
372923
+ return policy;
372924
+ }
373078
372925
  async function* process_operation_updated(item, op, handler) {
373079
372926
  for await (const transition of process_operation_doApply(item, op, handler)) {
373080
372927
  yield transition;
@@ -373099,6 +372946,7 @@ function isDestroyRetry(item) {
373099
372946
  return false;
373100
372947
  }
373101
372948
  async function* process_operation_sync(item, op, handler, syncPolicy, generalPolicy) {
372949
+ let doResult = '';
373102
372950
  if (!syncPolicy) {
373103
372951
  operator_src_logger.debug(`The Terraform processor is only observing item '${item.kind}/${item.metadata.name}' because no sync policy was found for operation '${op}'.`);
373104
372952
  yield* doPlanJSONFormat(item, op, handler);
@@ -373115,23 +372963,30 @@ async function* process_operation_sync(item, op, handler, syncPolicy, generalPol
373115
372963
  break;
373116
372964
  }
373117
372965
  case 'observe': {
373118
- yield* doPlanJSONFormat(item, op, handler);
372966
+ yield* doPlanJSONFormat(item, op, handler, (result) => {
372967
+ doResult = result;
372968
+ });
373119
372969
  break;
373120
372970
  }
373121
372971
  default: {
373122
372972
  operator_src_logger.debug(`The Terraform processor detected a sync policy '${syncPolicy}' for item '${item.kind}/${item.metadata.name}' that is not supported.`);
373123
- yield* doPlanJSONFormat(item, op, handler);
372973
+ yield* doPlanJSONFormat(item, op, handler, (result) => {
372974
+ doResult = result;
372975
+ });
373124
372976
  break;
373125
372977
  }
373126
372978
  }
373127
372979
  }
373128
- yield {
373129
- item,
373130
- reason: op,
373131
- type: 'SYNCHRONIZED',
373132
- status: 'True',
373133
- message: 'Sync process finished',
373134
- };
372980
+ operator_src_logger.debug(`doResult is ${doResult}`);
372981
+ if (doResult === 'SYNC_SUCCESS') {
372982
+ yield {
372983
+ item,
372984
+ reason: op,
372985
+ type: 'SYNCHRONIZED',
372986
+ status: 'True',
372987
+ message: 'Sync process finished',
372988
+ };
372989
+ }
373135
372990
  }
373136
372991
  async function* process_operation_markedToDeletion(item, op, handler) {
373137
372992
  let error = false;
@@ -373530,10 +373385,12 @@ function resolveReferences(item, deps) {
373530
373385
  try {
373531
373386
  const references = {};
373532
373387
  const itemReferences = item.spec.references;
373533
- console.dir(itemReferences);
373534
373388
  // if(!process.env.TONISILLO) process.exit(1)
373535
373389
  for (const iRef of itemReferences) {
373536
373390
  const ref = deps[`${iRef.ref.kind}-${iRef.ref.name}`];
373391
+ if (iRef.ref.kind === 'Secret') {
373392
+ ref.secret = ref.cr;
373393
+ }
373537
373394
  if (!ref) {
373538
373395
  throw new Error(`Reference ${iRef.ref.kind}-${iRef.ref.name} not found`);
373539
373396
  }
@@ -373731,7 +373588,7 @@ const processOperationPlan_TF_PROJECTS_PATH = '/tmp/tfworkspaces';
373731
373588
  function processOperationPlan(item, op, handler) {
373732
373589
  try {
373733
373590
  processOperationPlan_clearLocalTfProjects();
373734
- const policy = getPolicy(item, 'firestartr.dev/policy');
373591
+ const policy = processOperationPlan_getPolicy(item);
373735
373592
  if (policy === 'observe' || policy === 'apply') {
373736
373593
  return processOperationPlan_plan(item, op, handler);
373737
373594
  }
@@ -374190,6 +374047,12 @@ function processOperationPlan_getErrorOutputMessage(cr, key, ref) {
374190
374047
  throw new Error(`❌ Source ${cr.spec.source} not supported`);
374191
374048
  }
374192
374049
  }
374050
+ function processOperationPlan_getPolicy(item) {
374051
+ const policy = item.metadata.annotations &&
374052
+ item.metadata.annotations['firestartr.dev/policy'];
374053
+ if (policy)
374054
+ return policy;
374055
+ }
374193
374056
 
374194
374057
  ;// CONCATENATED MODULE: ../operator/src/ctx.ts
374195
374058
  class Ctx {
@@ -374462,6 +374325,7 @@ var sdk_metrics_build_src = __nccwpck_require__(84016);
374462
374325
 
374463
374326
 
374464
374327
 
374328
+
374465
374329
  const INTERVAL_IN_SEGS = 60;
374466
374330
  class CRStateMetrics {
374467
374331
  constructor(kind, namespace, meter) {
@@ -374484,6 +374348,9 @@ class CRStateMetrics {
374484
374348
  this.deletedGauge = meter.createGauge('firestartr_deleted_total', {
374485
374349
  description: 'Total number of CRs in DELETED state',
374486
374350
  });
374351
+ this.errorOnSyncGauge = meter.createGauge('firestartr_error_on_sync_total', {
374352
+ description: 'Total number of CRs with failed SYNCs',
374353
+ });
374487
374354
  this.namespace = namespace;
374488
374355
  }
374489
374356
  async start() {
@@ -374512,10 +374379,18 @@ class CRStateMetrics {
374512
374379
  let errorCount = 0;
374513
374380
  let planningCount = 0;
374514
374381
  let deletedCount = 0;
374382
+ let errorOnSyncCount = 0;
374515
374383
  for (const item of items) {
374516
374384
  const status = item.status?.conditions.find((condition) => condition.type !== 'SYNCHRONIZED' && condition.status === 'True');
374517
374385
  if (!status)
374518
374386
  continue;
374387
+ const syncCondition = item.status.conditions.find((condition) => {
374388
+ return condition.type === 'SYNCHRONIZED';
374389
+ });
374390
+ if (syncCondition &&
374391
+ syncCondition.message === SYNC_DEFAULT_ERROR_MESSAGE) {
374392
+ errorOnSyncCount++;
374393
+ }
374519
374394
  switch (status.type) {
374520
374395
  case 'PROVISIONED':
374521
374396
  provisionedCount++;
@@ -374561,6 +374436,10 @@ class CRStateMetrics {
374561
374436
  namespace: this.namespace,
374562
374437
  kind: this.kind,
374563
374438
  });
374439
+ this.errorOnSyncGauge.record(errorOnSyncCount, {
374440
+ namespace: this.namespace,
374441
+ kind: this.kind,
374442
+ });
374564
374443
  }
374565
374444
  catch (err) {
374566
374445
  console.log(`CRStateMetrics: update ${err}`);