@firestartr/cli 1.59.3 → 1.60.0

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 (32) hide show
  1. package/build/index.js +623 -78
  2. package/build/packages/catalog_common/index.d.ts +3 -0
  3. package/build/packages/catalog_common/src/tokenizer/index.d.ts +27 -0
  4. package/build/packages/cdk8s_renderer/src/claims/base/schemas/argodeploy.schema.d.ts +1 -0
  5. package/build/packages/cdk8s_renderer/src/claims/base/schemas/common-meta.schema.d.ts +46 -0
  6. package/build/packages/cdk8s_renderer/src/claims/base/schemas/component.schema.d.ts +1 -0
  7. package/build/packages/cdk8s_renderer/src/claims/base/schemas/group.schema.d.ts +1 -0
  8. package/build/packages/cdk8s_renderer/src/claims/base/schemas/index.d.ts +237 -0
  9. package/build/packages/cdk8s_renderer/src/claims/base/schemas/orgwebhook.schema.d.ts +1 -0
  10. package/build/packages/cdk8s_renderer/src/claims/base/schemas/secrets.schema.d.ts +1 -0
  11. package/build/packages/cdk8s_renderer/src/claims/base/schemas/tfworkspace.schema.d.ts +1 -0
  12. package/build/packages/cdk8s_renderer/src/claims/base/schemas/user.schema.d.ts +1 -0
  13. package/build/packages/cdk8s_renderer/src/claims/external-secrets/external-secrets.schema.d.ts +12 -0
  14. package/build/packages/cdk8s_renderer/src/claims/external-secrets/index.d.ts +12 -0
  15. package/build/packages/cdk8s_renderer/src/claims/github/component.schema.d.ts +136 -0
  16. package/build/packages/cdk8s_renderer/src/claims/github/group.schema.d.ts +11 -0
  17. package/build/packages/cdk8s_renderer/src/claims/github/index.d.ts +167 -0
  18. package/build/packages/cdk8s_renderer/src/claims/github/orgwebhook.schema.d.ts +9 -0
  19. package/build/packages/cdk8s_renderer/src/claims/github/user.schema.d.ts +11 -0
  20. package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/index.d.ts +5 -0
  21. package/build/packages/cdk8s_renderer/src/claims/tfworkspaces/terraform.schema.d.ts +5 -0
  22. package/build/packages/importer/src/decanter/gh/github_repo.d.ts +2 -0
  23. package/build/packages/importer/src/utils/codeowner.d.ts +5 -0
  24. package/build/packages/importer/src/utils/nomicon.d.ts +1 -0
  25. package/build/packages/operator/src/definitions.d.ts +1 -0
  26. package/build/packages/operator/src/informer.d.ts +1 -0
  27. package/build/packages/terraform_provisioner/index.d.ts +2 -1
  28. package/build/packages/terraform_provisioner/src/process_handler.d.ts +7 -0
  29. package/build/packages/terraform_provisioner/src/project_tf.d.ts +5 -1
  30. package/build/packages/terraform_provisioner/src/project_tf_remote.d.ts +4 -0
  31. package/build/packages/terraform_provisioner/src/utils.d.ts +5 -4
  32. package/package.json +1 -1
package/build/index.js CHANGED
@@ -346942,6 +346942,69 @@ function policiesAreCompatible(syncPolicy, generalPolicy) {
346942
346942
  FIRESTARTR_POLICIES: FIRESTARTR_POLICIES,
346943
346943
  });
346944
346944
 
346945
+ ;// CONCATENATED MODULE: ../catalog_common/src/tokenizer/index.ts
346946
+ class SimpleTokenizer {
346947
+ /**
346948
+ * Pass the regex here (it automatically makes it global so it finds ALL matches)
346949
+ */
346950
+ constructor(regex) {
346951
+ const flags = regex.flags.includes('g') ? regex.flags : regex.flags + 'g';
346952
+ this.regex = new RegExp(regex.source, flags);
346953
+ }
346954
+ /**
346955
+ * Turn the whole string into a list of tokens:
346956
+ * - 'text' = normal text between matches
346957
+ * - 'match' = whatever your regex found
346958
+ */
346959
+ tokenize(input) {
346960
+ this.regex.lastIndex = 0;
346961
+ const tokens = [];
346962
+ let lastIndex = 0;
346963
+ let match;
346964
+ while ((match = this.regex.exec(input)) !== null) {
346965
+ // Text before this match
346966
+ if (match.index > lastIndex) {
346967
+ tokens.push({
346968
+ type: 'text',
346969
+ value: input.slice(lastIndex, match.index),
346970
+ index: lastIndex,
346971
+ });
346972
+ }
346973
+ // The matched part
346974
+ tokens.push({
346975
+ type: 'match',
346976
+ value: match[0],
346977
+ index: match.index,
346978
+ groups: match.slice(1), // any capture groups you defined
346979
+ });
346980
+ if (match[0].length === 0) {
346981
+ this.regex.lastIndex += 1;
346982
+ }
346983
+ lastIndex = this.regex.lastIndex;
346984
+ }
346985
+ // Remaining text after the last match
346986
+ if (lastIndex < input.length) {
346987
+ tokens.push({
346988
+ type: 'text',
346989
+ value: input.slice(lastIndex),
346990
+ index: lastIndex,
346991
+ });
346992
+ }
346993
+ return tokens;
346994
+ }
346995
+ /**
346996
+ * Replace only the matched tokens by calling the function.
346997
+ */
346998
+ replace(input, replacer) {
346999
+ return this.tokenize(input)
347000
+ .map((token) => (token.type === 'match' ? replacer(token) : token.value))
347001
+ .join('');
347002
+ }
347003
+ }
347004
+ /* harmony default export */ const tokenizer = ({
347005
+ SimpleTokenizer,
347006
+ });
347007
+
346945
347008
  // EXTERNAL MODULE: ../../node_modules/cron-parser/dist/index.js
346946
347009
  var cron_parser_dist = __nccwpck_require__(98370);
346947
347010
  ;// CONCATENATED MODULE: ../catalog_common/src/cron.ts
@@ -346984,6 +347047,7 @@ function getCronNextInterval(cronLine, tz) {
346984
347047
 
346985
347048
 
346986
347049
 
347050
+
346987
347051
  /* harmony default export */ const catalog_common = ({
346988
347052
  io: io,
346989
347053
  generic: generic,
@@ -346993,6 +347057,7 @@ function getCronNextInterval(cronLine, tz) {
346993
347057
  features: features,
346994
347058
  policies: policies,
346995
347059
  logger: logger_logger,
347060
+ tokenizer: tokenizer,
346996
347061
  cron: {
346997
347062
  validateCron: validateCron,
346998
347063
  isValidCron: isValidCron,
@@ -353830,6 +353895,7 @@ async function getOrgTeamsDirectAccess(org) {
353830
353895
  nodes {
353831
353896
  id
353832
353897
  name
353898
+ slug
353833
353899
  repositories {
353834
353900
  edges {
353835
353901
  permission
@@ -353859,7 +353925,7 @@ function transformGraphQLResponse(response) {
353859
353925
  teams.forEach((team) => {
353860
353926
  const teamName = team.name;
353861
353927
  const teamId = team.id;
353862
- result.teams[teamName] = { id: teamId };
353928
+ result.teams[teamName] = { id: teamId, slug: team.slug };
353863
353929
  const repositories = team.repositories.edges;
353864
353930
  repositories.forEach((repoEdge) => {
353865
353931
  const repoName = repoEdge.node.name;
@@ -353867,7 +353933,10 @@ function transformGraphQLResponse(response) {
353867
353933
  if (!result.repositories[repoName]) {
353868
353934
  result.repositories[repoName] = {};
353869
353935
  }
353870
- result.repositories[repoName][teamName] = permission;
353936
+ result.repositories[repoName][teamName] = {
353937
+ permission,
353938
+ slug: team.slug,
353939
+ };
353871
353940
  });
353872
353941
  });
353873
353942
  return result;
@@ -355229,6 +355298,7 @@ class BranchStrategiesInitializer extends InitializerPatches {
355229
355298
  cr.spec.repo.defaultBranch = claim.providers.github.defaultBranch;
355230
355299
  cr.spec.branchProtections = [];
355231
355300
  }
355301
+ cr.spec.branchProtections = cr.spec?.branchProtections ?? [];
355232
355302
  delete cr.metadata.annotations[catalog_common.generic.getFirestartrAnnotation('branchStrategy')];
355233
355303
  return cr;
355234
355304
  },
@@ -356599,6 +356669,8 @@ class BranchStrategiesExpander extends GlobalSection {
356599
356669
  claim.providers.github.branchStrategy.defaultBranch;
356600
356670
  cr.spec.branchProtections = previousCR.spec.branchProtections;
356601
356671
  }
356672
+ // fallback to empty array
356673
+ cr.spec.branchProtections = cr.spec?.branchProtections ?? [];
356602
356674
  delete cr.metadata.annotations[catalog_common.generic.getFirestartrAnnotation('branchStrategy')];
356603
356675
  return cr;
356604
356676
  },
@@ -357922,6 +357994,42 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
357922
357994
  },
357923
357995
  additionalProperties: false,
357924
357996
  },
357997
+ GithubRules: {
357998
+ $id: 'firestartr.dev://common/FirestartrGithubRules',
357999
+ type: 'object',
358000
+ properties: {
358001
+ path: { type: 'string' },
358002
+ owners: {
358003
+ type: 'array',
358004
+ items: {
358005
+ $ref: 'firestartr.dev://common/FirestartrOwnerRef',
358006
+ },
358007
+ },
358008
+ },
358009
+ required: ['path', 'owners'],
358010
+ additionalProperties: false,
358011
+ },
358012
+ GithubSync: {
358013
+ $id: 'firestartr.dev://common/FirestartrGithubSync',
358014
+ type: 'object',
358015
+ properties: {
358016
+ enabled: { type: 'boolean' },
358017
+ period: {
358018
+ type: 'string',
358019
+ pattern: '^[0-9]+[smhd]$',
358020
+ },
358021
+ policy: { type: 'string' },
358022
+ schedule: { type: 'string' },
358023
+ schedule_timezone: { type: 'string' },
358024
+ },
358025
+ additionalProperties: false,
358026
+ required: ['enabled'],
358027
+ },
358028
+ TfStateKey: {
358029
+ $id: 'firestartr.dev://common/TerraformStateKey',
358030
+ type: 'string',
358031
+ pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12,}$',
358032
+ },
357925
358033
  },
357926
358034
  });
357927
358035
 
@@ -357957,6 +358065,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
357957
358065
  $ref: 'firestartr.dev://github/GithubTeamClaim',
357958
358066
  },
357959
358067
  },
358068
+ additionalProperties: false,
357960
358069
  },
357961
358070
  },
357962
358071
  },
@@ -357988,6 +358097,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
357988
358097
  $ref: 'firestartr.dev://github/GithubUserClaim',
357989
358098
  },
357990
358099
  },
358100
+ additionalProperties: false,
357991
358101
  },
357992
358102
  },
357993
358103
  },
@@ -358033,6 +358143,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358033
358143
  $ref: 'firestartr.dev://github/GithubComponentClaim',
358034
358144
  },
358035
358145
  },
358146
+ additionalProperties: false,
358036
358147
  },
358037
358148
  },
358038
358149
  required: ['owner'],
@@ -358122,6 +358233,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358122
358233
  $ref: 'firestartr.dev://terraform/TerraformProvider',
358123
358234
  },
358124
358235
  },
358236
+ additionalProperties: false,
358125
358237
  required: ['terraform'],
358126
358238
  },
358127
358239
  },
@@ -358159,6 +358271,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358159
358271
  $ref: 'firestartr.dev://argocd/ArgoCDProvider',
358160
358272
  },
358161
358273
  },
358274
+ additionalProperties: false,
358162
358275
  required: ['argocd'],
358163
358276
  },
358164
358277
  },
@@ -358195,6 +358308,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358195
358308
  $ref: 'firestartr.dev://secrets/ExternalSecretsProvider',
358196
358309
  },
358197
358310
  },
358311
+ additionalProperties: false,
358198
358312
  required: ['external_secrets'],
358199
358313
  },
358200
358314
  },
@@ -358234,6 +358348,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358234
358348
  $ref: 'firestartr.dev://github/GithubOrgWebhookClaim',
358235
358349
  },
358236
358350
  },
358351
+ additionalProperties: false,
358237
358352
  },
358238
358353
  },
358239
358354
  required: ['owner'],
@@ -358258,6 +358373,15 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358258
358373
  {
358259
358374
  type: 'object',
358260
358375
  properties: {
358376
+ name: {
358377
+ type: 'string',
358378
+ },
358379
+ tfStateKey: {
358380
+ $ref: 'firestartr.dev://common/TerraformStateKey',
358381
+ },
358382
+ sync: {
358383
+ $ref: 'firestartr.dev://common/FirestartrGithubSync',
358384
+ },
358261
358385
  privacy: {
358262
358386
  type: 'string',
358263
358387
  enum: ['closed', 'secret'],
@@ -358269,6 +358393,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358269
358393
  $ref: 'firestartr.dev://common/ClaimName',
358270
358394
  },
358271
358395
  },
358396
+ additionalProperties: false,
358272
358397
  required: ['org', 'privacy'],
358273
358398
  },
358274
358399
  ],
@@ -358293,6 +358418,15 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358293
358418
  {
358294
358419
  type: 'object',
358295
358420
  properties: {
358421
+ name: {
358422
+ type: 'string',
358423
+ },
358424
+ tfStateKey: {
358425
+ $ref: 'firestartr.dev://common/TerraformStateKey',
358426
+ },
358427
+ sync: {
358428
+ $ref: 'firestartr.dev://common/FirestartrGithubSync',
358429
+ },
358296
358430
  role: {
358297
358431
  type: 'string',
358298
358432
  enum: ['admin', 'member'],
@@ -358301,6 +358435,7 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358301
358435
  $ref: 'firestartr.dev://common/ClaimName',
358302
358436
  },
358303
358437
  },
358438
+ additionalProperties: false,
358304
358439
  required: ['org', 'role'],
358305
358440
  },
358306
358441
  ],
@@ -358331,14 +358466,125 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358331
358466
  type: 'string',
358332
358467
  description: 'The github repo name',
358333
358468
  },
358469
+ tfStateKey: {
358470
+ $ref: 'firestartr.dev://common/TerraformStateKey',
358471
+ },
358334
358472
  orgPermissions: {
358335
358473
  type: 'string',
358336
358474
  description: 'The level of org Permission',
358337
358475
  },
358476
+ sync: {
358477
+ $ref: 'firestartr.dev://common/FirestartrGithubSync',
358478
+ },
358479
+ technology: {
358480
+ type: 'object',
358481
+ properties: {
358482
+ stack: { type: 'string' },
358483
+ version: { type: 'string' },
358484
+ },
358485
+ additionalProperties: false,
358486
+ required: ['stack', 'version'],
358487
+ },
358488
+ defaultBranch: {
358489
+ type: 'string',
358490
+ },
358491
+ branchStrategy: {
358492
+ type: 'object',
358493
+ description: 'A branch strategy for a claim',
358494
+ properties: {
358495
+ name: {
358496
+ type: 'string',
358497
+ },
358498
+ defaultBranch: {
358499
+ type: 'string',
358500
+ },
358501
+ },
358502
+ additionalProperties: false,
358503
+ required: ['name'],
358504
+ },
358505
+ additionalBranches: {
358506
+ type: 'array',
358507
+ items: {
358508
+ type: 'object',
358509
+ properties: {
358510
+ name: { type: 'string' },
358511
+ orphan: { type: 'boolean' },
358512
+ },
358513
+ additionalProperties: false,
358514
+ required: ['name', 'orphan'],
358515
+ },
358516
+ },
358517
+ actions: {
358518
+ type: 'object',
358519
+ description: 'Actions configuration',
358520
+ properties: {
358521
+ oidc: {
358522
+ type: 'object',
358523
+ properties: {
358524
+ useDefault: { type: 'boolean' },
358525
+ includeClaimKeys: {
358526
+ type: 'array',
358527
+ items: { type: 'string' },
358528
+ },
358529
+ },
358530
+ additionalProperties: false,
358531
+ },
358532
+ },
358533
+ additionalProperties: false,
358534
+ required: ['oidc'],
358535
+ },
358338
358536
  archiveOnDestroy: {
358339
358537
  type: 'boolean',
358340
358538
  description: 'whether this repo should be archived when the claim is deleted',
358341
358539
  },
358540
+ allowMergeCommit: {
358541
+ type: 'boolean',
358542
+ },
358543
+ allowSquashMerge: {
358544
+ type: 'boolean',
358545
+ },
358546
+ allowRebaseMerge: {
358547
+ type: 'boolean',
358548
+ },
358549
+ allowAutoMerge: {
358550
+ type: 'boolean',
358551
+ },
358552
+ deleteBranchOnMerge: {
358553
+ type: 'boolean',
358554
+ },
358555
+ autoInit: {
358556
+ type: 'boolean',
358557
+ },
358558
+ allowUpdateBranch: {
358559
+ type: 'boolean',
358560
+ },
358561
+ hasIssues: {
358562
+ type: 'boolean',
358563
+ },
358564
+ hasWiki: {
358565
+ type: 'boolean',
358566
+ },
358567
+ pages: {
358568
+ type: 'object',
358569
+ properties: {
358570
+ cname: { type: 'string' },
358571
+ source: {
358572
+ type: 'object',
358573
+ properties: {
358574
+ branch: { type: 'string' },
358575
+ path: { type: 'string' },
358576
+ },
358577
+ additionalProperties: false,
358578
+ },
358579
+ },
358580
+ additionalProperties: false,
358581
+ },
358582
+ additionalRules: {
358583
+ type: 'array',
358584
+ items: {
358585
+ $ref: 'firestartr.dev://common/FirestartrGithubRules',
358586
+ },
358587
+ },
358342
358588
  visibility: {
358343
358589
  type: 'string',
358344
358590
  enum: ['private', 'public', 'internal'],
@@ -358367,8 +358613,14 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358367
358613
  pattern: '^[a-z0-9][a-z0-9-]*$',
358368
358614
  },
358369
358615
  },
358616
+ overrides: {
358617
+ type: 'object',
358618
+ properties: {},
358619
+ additionalProperties: true,
358620
+ },
358370
358621
  },
358371
- required: ['visibility', 'org'],
358622
+ additionalProperties: false,
358623
+ required: ['visibility', 'org', 'branchStrategy'],
358372
358624
  },
358373
358625
  ],
358374
358626
  },
@@ -358390,6 +358642,12 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358390
358642
  {
358391
358643
  type: 'object',
358392
358644
  properties: {
358645
+ name: {
358646
+ type: 'string',
358647
+ },
358648
+ tfStateKey: {
358649
+ $ref: 'firestartr.dev://common/TerraformStateKey',
358650
+ },
358393
358651
  orgName: {
358394
358652
  $ref: 'firestartr.dev://common/ClaimName',
358395
358653
  },
@@ -358420,9 +358678,11 @@ const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createReq
358420
358678
  },
358421
358679
  },
358422
358680
  },
358681
+ additionalProperties: false,
358423
358682
  required: ['url', 'contentType', 'events', 'secretRef'],
358424
358683
  },
358425
358684
  },
358685
+ additionalProperties: false,
358426
358686
  required: ['orgName', 'webhook'],
358427
358687
  },
358428
358688
  ],
@@ -358626,6 +358886,9 @@ const GithubSchemas = [
358626
358886
  name: {
358627
358887
  type: 'string',
358628
358888
  },
358889
+ tfStateKey: {
358890
+ $ref: 'firestartr.dev://common/TerraformStateKey',
358891
+ },
358629
358892
  source: {
358630
358893
  type: 'string',
358631
358894
  enum: ['remote', 'inline', 'Remote', 'Inline'],
@@ -358717,6 +358980,7 @@ const GithubSchemas = [
358717
358980
  additionalProperties: false,
358718
358981
  },
358719
358982
  },
358983
+ additionalProperties: false,
358720
358984
  required: ['values', 'context', 'source', 'name'],
358721
358985
  },
358722
358986
  ],
@@ -358849,6 +359113,7 @@ const ArgoCDSchemas = [argocd_schema];
358849
359113
  enum: ['SecretStore', 'ClusterSecretStore'],
358850
359114
  },
358851
359115
  },
359116
+ additionalProperties: false,
358852
359117
  required: ['name'],
358853
359118
  },
358854
359119
  ExternalSecretsSection: {
@@ -358884,6 +359149,9 @@ const ArgoCDSchemas = [argocd_schema];
358884
359149
  template: { type: 'object' },
358885
359150
  secretName: { type: 'string' },
358886
359151
  refreshInterval: { type: 'string' },
359152
+ updatePolicy: { type: 'string' },
359153
+ deletionPolicy: { type: 'string' },
359154
+ conversionStrategy: { type: 'string' },
358887
359155
  generator: {
358888
359156
  type: 'object',
358889
359157
  properties: {
@@ -358906,19 +359174,15 @@ const ArgoCDSchemas = [argocd_schema];
358906
359174
  'Grafana',
358907
359175
  ],
358908
359176
  },
358909
- apiVersion: {
358910
- type: 'string',
358911
- },
358912
- conversionStrategy: {
358913
- type: 'string',
358914
- },
358915
- outputKey: {
358916
- type: 'string',
358917
- },
359177
+ apiVersion: { type: 'string' },
359178
+ conversionStrategy: { type: 'string' },
359179
+ outputKey: { type: 'string' },
358918
359180
  },
359181
+ additionalProperties: false,
358919
359182
  required: ['name'],
358920
359183
  },
358921
359184
  },
359185
+ additionalProperties: false,
358922
359186
  required: ['secretName', 'generator'],
358923
359187
  },
358924
359188
  },
@@ -366185,6 +366449,8 @@ function walkArray(arr, symbolsToResolve, renderClaim) {
366185
366449
 
366186
366450
 
366187
366451
 
366452
+
366453
+
366188
366454
  /*
366189
366455
  * Function called when rendering from the importer class.
366190
366456
  *
@@ -366198,6 +366464,14 @@ function walkArray(arr, symbolsToResolve, renderClaim) {
366198
366464
  *
366199
366465
  */
366200
366466
  async function renderFromImports(rClaims, crs = {}, catalogOutputDir = '/tmp/.catalog', crOutputDir = '/tmp/.resources') {
366467
+ // Apply claim defaults (same as runRenderer path does via loadClaim/patchClaim)
366468
+ let defaults;
366469
+ try {
366470
+ defaults = loadClaimDefaults();
366471
+ }
366472
+ catch (e) {
366473
+ cdk8s_renderer_src_logger.warn(`Could not load claim defaults: ${e.message}`);
366474
+ }
366201
366475
  // type: is the kind of the claim
366202
366476
  // value: is the imported-ref (the name in Github, can be with special characters, spaces, etc)
366203
366477
  const fSolver = (type, value) => {
@@ -366214,6 +366488,13 @@ async function renderFromImports(rClaims, crs = {}, catalogOutputDir = '/tmp/.ca
366214
366488
  cdk8s_renderer_src_logger.error(`Error while resolving imported-refs: ${e.message}`);
366215
366489
  throw new Error(`Error while resolving imported-refs: ${e.message}`);
366216
366490
  }
366491
+ // after resolving the imported-refs, we need to validate the claims again, and apply the defaults if needed
366492
+ for (const renderClaim of Object.values(rClaims)) {
366493
+ if (defaults) {
366494
+ renderClaim.claim = loader_patchClaim(renderClaim.claim, defaults);
366495
+ }
366496
+ validateClaim(renderClaim.claim, `firestartr.dev://common/${renderClaim.claim.kind}`);
366497
+ }
366217
366498
  const catalogScope = new lib.App({
366218
366499
  outdir: catalogOutputDir,
366219
366500
  outputFileExtension: '.yaml',
@@ -366839,10 +367120,61 @@ MemberCollectionGithubDecanter.collectionKind = 'gh-members';
366839
367120
  applyCollectionMixins(MemberCollectionGithubDecanter);
366840
367121
  /* harmony default export */ const github_member_collection = (MemberCollectionGithubDecanter);
366841
367122
 
367123
+ ;// CONCATENATED MODULE: ../importer/src/utils/codeowner.ts
367124
+ function extractFromCodeOwners(codeOwnersContent) {
367125
+ if (!codeOwnersContent) {
367126
+ return [];
367127
+ }
367128
+ return codeOwnersContent.split(/\r?\n/).flatMap((line) => {
367129
+ const trimmedLine = line.trim();
367130
+ // skip blank lines and full-line comments
367131
+ if (!trimmedLine || trimmedLine.startsWith('#')) {
367132
+ return [];
367133
+ }
367134
+ // strip inline comments before parsing owners
367135
+ const lineWithoutInlineComment = line.replace(/\s*#.*$/, '').trim();
367136
+ if (!lineWithoutInlineComment) {
367137
+ return [];
367138
+ }
367139
+ // CODEOWNERS format: <pattern> <owner1> [<owner2> ...]
367140
+ // first field is the path pattern; owners start from the second field
367141
+ const parts = lineWithoutInlineComment.split(/\s+/);
367142
+ if (parts.length < 2) {
367143
+ return [];
367144
+ }
367145
+ return parts
367146
+ .slice(1)
367147
+ .filter((part) => part.startsWith('@'))
367148
+ .map((owner) => ({
367149
+ full: owner,
367150
+ isTeam: owner.includes('/'),
367151
+ name: owner,
367152
+ }));
367153
+ });
367154
+ }
367155
+
367156
+ ;// CONCATENATED MODULE: ../importer/src/utils/nomicon.ts
367157
+ function transformRepoName(repoName) {
367158
+ // Convert to lowercase
367159
+ let transformedName = repoName.toLowerCase();
367160
+ const specialCharsRegex = /[._]/g;
367161
+ if (specialCharsRegex.test(transformedName)) {
367162
+ transformedName = transformedName.replace(/[._]/g, '');
367163
+ // we add a random 2 letter suffix
367164
+ return (transformedName + '-imp-' + Math.random().toString(36).substring(2, 4));
367165
+ }
367166
+ else {
367167
+ return transformedName;
367168
+ }
367169
+ }
367170
+
366842
367171
  ;// CONCATENATED MODULE: ../importer/src/decanter/gh/github_repo.ts
366843
367172
 
366844
367173
 
366845
367174
 
367175
+
367176
+
367177
+
366846
367178
  const TYPE_MAP = {
366847
367179
  User: 'user',
366848
367180
  Team: 'group',
@@ -366860,7 +367192,7 @@ class RepoGithubDecanter extends GithubDecanter {
366860
367192
  version: this.VERSION(),
366861
367193
  type: 'service',
366862
367194
  lifecycle: 'production',
366863
- name: this.data.repoDetails.name,
367195
+ name: transformRepoName(this.data.repoDetails.name),
366864
367196
  };
366865
367197
  }
366866
367198
  __decantProviders() {
@@ -366913,6 +367245,52 @@ class RepoGithubDecanter extends GithubDecanter {
366913
367245
  });
366914
367246
  }
366915
367247
  }
367248
+ // only for validation
367249
+ __decantValidateCodeowners() {
367250
+ if (this.data.codeowners) {
367251
+ const owners = extractFromCodeOwners(this.data.codeowners);
367252
+ const normalizeTeamIdentifier = (value) => {
367253
+ const normalizedValue = (value.startsWith('@') ? value.slice(1) : value).toLowerCase();
367254
+ if (!normalizedValue.includes('/')) {
367255
+ return normalizedValue;
367256
+ }
367257
+ const [org, slug, ...rest] = normalizedValue.split('/');
367258
+ if (!org || !slug || rest.length > 0) {
367259
+ return null;
367260
+ }
367261
+ return org === this.org.toLowerCase() ? slug : null;
367262
+ };
367263
+ const isInTeams = (teamSlugInCodeowners) => {
367264
+ const normalizedTeamSlug = normalizeTeamIdentifier(teamSlugInCodeowners);
367265
+ if (!normalizedTeamSlug) {
367266
+ return false;
367267
+ }
367268
+ return this.data.teamsAndMembers.teams.some((team) => {
367269
+ return team.slug?.toLowerCase() === normalizedTeamSlug;
367270
+ });
367271
+ };
367272
+ const isInUsers = (userName) => {
367273
+ // strip the leading '@' for users (CODEOWNERS format: @username)
367274
+ // and normalize to lowercase for case-insensitive comparison
367275
+ const normalizedUserName = (userName.startsWith('@') ? userName.slice(1) : userName).toLowerCase();
367276
+ return (this.data.teamsAndMembers.directMembers.some((member) => member.name?.toLowerCase() === normalizedUserName) ||
367277
+ this.data.teamsAndMembers.outsideMembers.some((member) => member.name?.toLowerCase() === normalizedUserName));
367278
+ };
367279
+ // let's validate that every element in the
367280
+ // CODEOWNERS file is either a team or a user in the repository,
367281
+ // otherwise we will have dangling references in the claim which will cause issues down the line
367282
+ for (const owner of owners) {
367283
+ if (owner.isTeam && !isInTeams(owner.name)) {
367284
+ importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner.name} which is not present in the repository's teams.`);
367285
+ throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner.name} which is not present in the repository's teams.`);
367286
+ }
367287
+ else if (!owner.isTeam && !isInUsers(owner.name)) {
367288
+ importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner.name} which is not present in the repository's collaborators.`);
367289
+ throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner.name} which is not present in the repository's collaborators.`);
367290
+ }
367291
+ }
367292
+ }
367293
+ }
366916
367294
  __decantRelations() {
366917
367295
  const directMaintainers = this.data.teamsAndMembers.directMembers
366918
367296
  .filter((member) => member.role === 'maintain')
@@ -366922,7 +367300,7 @@ class RepoGithubDecanter extends GithubDecanter {
366922
367300
  const outsideMaintainers = this.data.teamsAndMembers.outsideMembers
366923
367301
  .filter((member) => member.role === 'maintain')
366924
367302
  .map((member) => {
366925
- return `collaborator:${member.name}`;
367303
+ return `collaborator:${member.name.toLowerCase()}`;
366926
367304
  });
366927
367305
  const teamMaintainers = this.data.teamsAndMembers.teams
366928
367306
  .filter((team) => team.role === 'maintain')
@@ -366947,7 +367325,7 @@ class RepoGithubDecanter extends GithubDecanter {
366947
367325
  const outsideAdmins = this.data.teamsAndMembers.outsideMembers
366948
367326
  .filter((member) => member.role === 'admin')
366949
367327
  .map((member) => {
366950
- return `collaborator:${member.name}`;
367328
+ return `collaborator:${member.name.toLowerCase()}`;
366951
367329
  });
366952
367330
  const teamAdmins = this.data.teamsAndMembers.teams
366953
367331
  .filter((team) => team.role === 'admin')
@@ -366956,13 +367334,6 @@ class RepoGithubDecanter extends GithubDecanter {
366956
367334
  });
366957
367335
  const admins = directAdmins.concat(outsideAdmins).concat(teamAdmins);
366958
367336
  const overrides = {};
366959
- if (admins && admins.length > 0) {
366960
- this.__patchClaim({
366961
- op: 'add',
366962
- value: admins[0],
366963
- path: '/owner',
366964
- });
366965
- }
366966
367337
  if (admins && admins.length > 1) {
366967
367338
  overrides['additionalAdmins'] = [];
366968
367339
  for (let i = 1; i < admins.length; i++) {
@@ -366982,7 +367353,7 @@ class RepoGithubDecanter extends GithubDecanter {
366982
367353
  const outsideWriters = this.data.teamsAndMembers.outsideMembers
366983
367354
  .filter((member) => member.role === 'push')
366984
367355
  .map((member) => {
366985
- return `collaborator:${member.name}`;
367356
+ return `collaborator:${member.name.toLowerCase()}`;
366986
367357
  });
366987
367358
  const teamWriters = this.data.teamsAndMembers.teams
366988
367359
  .filter((team) => ['push', 'write'].includes(team.role))
@@ -367006,7 +367377,7 @@ class RepoGithubDecanter extends GithubDecanter {
367006
367377
  const outsideReaders = this.data.teamsAndMembers.outsideMembers
367007
367378
  .filter((member) => member.role === 'pull')
367008
367379
  .map((member) => {
367009
- return `collaborator:${member.name}`;
367380
+ return `collaborator:${member.name.toLowerCase()}`;
367010
367381
  });
367011
367382
  const teamReaders = this.data.teamsAndMembers.teams
367012
367383
  .filter((team) => ['pull', 'read'].includes(team.role))
@@ -367034,7 +367405,8 @@ class RepoGithubDecanter extends GithubDecanter {
367034
367405
  const teams = Object.keys(this.githubTeams).map((teamName) => {
367035
367406
  return {
367036
367407
  name: teamName,
367037
- role: this.githubTeams[teamName].toLowerCase(),
367408
+ role: this.githubTeams[teamName].permission.toLowerCase(),
367409
+ slug: this.githubTeams[teamName].slug,
367038
367410
  };
367039
367411
  });
367040
367412
  this.data['teamsAndMembers']['teams'] = teams;
@@ -367062,6 +367434,28 @@ class RepoGithubDecanter extends GithubDecanter {
367062
367434
  }
367063
367435
  this.data['branchStrategy'] = { kind: value, data: bpInfo };
367064
367436
  }
367437
+ async __gatherCodeowners() {
367438
+ const codeownersPaths = [
367439
+ '.github/CODEOWNERS',
367440
+ 'CODEOWNERS',
367441
+ 'docs/CODEOWNERS',
367442
+ ];
367443
+ for (const codeownersPath of codeownersPaths) {
367444
+ try {
367445
+ const codeowners = await github_0.repo.getContent(codeownersPath, this.data.repoDetails.name, this.org);
367446
+ this.data['codeowners'] = codeowners;
367447
+ return;
367448
+ }
367449
+ catch (e) {
367450
+ const status = e?.status ?? e?.response?.status;
367451
+ if (status === 404) {
367452
+ continue;
367453
+ }
367454
+ throw e;
367455
+ }
367456
+ }
367457
+ importer_src_logger.info(`No CODEOWNERS file found for ${this.data.repoDetails.name}, skipping.`);
367458
+ }
367065
367459
  async __adaptInitializerBranchStrategies(_claim) {
367066
367460
  const bpData = this.data.branchStrategy.data;
367067
367461
  if (this.data.branchStrategy.kind === 'custom') {
@@ -367128,7 +367522,8 @@ class RepoCollectionGithubDecanter extends GithubDecanter {
367128
367522
  const filteredRepos = await this.filter(RepoCollectionGithubDecanter.collectionKind, filters, repoList.map((repo) => repo.name));
367129
367523
  for (const repoName of filteredRepos) {
367130
367524
  const repoInfo = await this.github.repo.getRepoInfo(this.org, repoName);
367131
- repos.push(new RepoGithubDecanter({ repoDetails: repoInfo }, this.org, directAccessRepos?.[repoName]));
367525
+ const repoDecanter = new RepoGithubDecanter({ repoDetails: repoInfo }, this.org, directAccessRepos?.[repoName]);
367526
+ repos.push(repoDecanter);
367132
367527
  }
367133
367528
  this.data['collection'] = repos;
367134
367529
  return repos;
@@ -367147,6 +367542,13 @@ applyCollectionMixins(RepoCollectionGithubDecanter);
367147
367542
 
367148
367543
 
367149
367544
 
367545
+ // A single claim can render multiple CRs.
367546
+ // Some of those rendered kinds are derived/child resources whose parent is the
367547
+ // main CR for the claim, so they do not correspond to claim files that should be moved.
367548
+ const CHILD_CR_KINDS = [
367549
+ 'FirestartrGithubRepositorySecretsSection',
367550
+ 'FirestartrGithubRepositoryFeature',
367551
+ ];
367150
367552
  let previousCRs = {};
367151
367553
  const collections = {
367152
367554
  GroupCollectionGithubDecanter: github_group_collection,
@@ -367217,7 +367619,10 @@ async function moveCRsAndClaims(crs, org, claimsPath, resourcesPath) {
367217
367619
  importer_src_logger.info(`📝 Moving: CR with kind: ${crs[k].kind} and name: ${crs[k].metadata.name} to wet repository`);
367218
367620
  importedResources.push(`${crs[k].kind} ${crs[k].metadata.name}`);
367219
367621
  catalog_common.io.moveFile(getCrPath(tmpRenderedCrsPath, crs[k]), getCrPath(resourcesPath, crs[k]));
367220
- catalog_common.io.moveFile(getClaimPathFromCR(randomFolder, crs[k]), getClaimPathFromCR(claimsPath, crs[k]));
367622
+ // We only want to execute the move on claims based on parent CRs, so we're omitting child CRs
367623
+ if (!CHILD_CR_KINDS.includes(crs[k].kind)) {
367624
+ catalog_common.io.moveFile(getClaimPathFromCR(randomFolder, crs[k]), getClaimPathFromCR(claimsPath, crs[k]));
367625
+ }
367221
367626
  }
367222
367627
  catch (e) {
367223
367628
  console.error(e);
@@ -367689,6 +368094,25 @@ function definitions_getPluralFromKind(kind) {
367689
368094
  const plural = Object.keys(kindPluralMap).find((key) => kindPluralMap[key] === kind);
367690
368095
  return plural;
367691
368096
  }
368097
+ const DAY_SECONDS = 24 * 60 * 60;
368098
+ const TIMEOUTS = {
368099
+ // expressed in seconds
368100
+ RENAMED: DAY_SECONDS,
368101
+ UPDATED: DAY_SECONDS,
368102
+ CREATED: DAY_SECONDS,
368103
+ RETRY: 120 * 60,
368104
+ MARKED_TO_DELETION: DAY_SECONDS,
368105
+ SYNC: DAY_SECONDS,
368106
+ NOTHING: 10,
368107
+ };
368108
+ function getTimeoutForOperation(operation) {
368109
+ if (operation in TIMEOUTS) {
368110
+ return TIMEOUTS[operation];
368111
+ }
368112
+ else {
368113
+ throw new Error(`getTimeoutForOperation: Unknown operation: ${operation}`);
368114
+ }
368115
+ }
367692
368116
 
367693
368117
  ;// CONCATENATED MODULE: ../operator/src/pr-annotation.ts
367694
368118
 
@@ -369200,6 +369624,19 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
369200
369624
  itemPath: () => informer_itemPath(pluralKind, workItem.item),
369201
369625
  error: () => retryCtl.errorReconciling(informer_itemPath(pluralKind, workItem.item)),
369202
369626
  success: () => retryCtl.successReconciling(informer_itemPath(pluralKind, workItem.item)),
369627
+ recommendedTimeout: () => {
369628
+ const customTimeoutAnnotation = catalog_common.generic.getFirestartrAnnotation('test-custom-timeout');
369629
+ let customTimeout = null;
369630
+ if ('annotations' in workItem.item.metadata &&
369631
+ customTimeoutAnnotation in workItem.item.metadata.annotations &&
369632
+ !isNaN(parseInt(workItem.item.metadata.annotations[customTimeoutAnnotation]))) {
369633
+ customTimeout = parseInt(workItem.item.metadata.annotations[customTimeoutAnnotation]);
369634
+ }
369635
+ else {
369636
+ customTimeout = getTimeoutForOperation(workItem.operation);
369637
+ }
369638
+ return customTimeout;
369639
+ },
369203
369640
  needsBlocking: (item, operation) => {
369204
369641
  if (kindsWithDependants.indexOf(item.kind) === -1) {
369205
369642
  return false;
@@ -370052,16 +370489,6 @@ function getQueueMetrics() {
370052
370489
  // "FirestartrGithubRepositoryFeature": 1,
370053
370490
  // "FirestartrTerraformWorkspacePlan": 1,
370054
370491
  // }
370055
- const TIMEOUTS = {
370056
- // expressed in seconds
370057
- RENAMED: 30 * 60,
370058
- UPDATED: 60 * 60,
370059
- CREATED: 60 * 60,
370060
- RETRY: 60 * 60,
370061
- MARKED_TO_DELETION: 60 * 60,
370062
- SYNC: 60 * 60,
370063
- NOTHING: 10,
370064
- };
370065
370492
  let INIT = false;
370066
370493
  /**
370067
370494
  * Pushes a WorkItem to the queue
@@ -370099,27 +370526,12 @@ async function processItem_loop() {
370099
370526
  if (w) {
370100
370527
  const logMessage = `${new Date().toISOString()} : Processing OPERATION: ${w.operation} ITEM: ${w.item.kind}/${w.item.metadata.name}`;
370101
370528
  catalog_common.io.writeLogFile('process_item', logMessage);
370102
- const timeout = createTimeout(w);
370103
370529
  operator_src_logger.info(`The processor is currently handling a '${w.operation}' operation for item '${w.item.kind}/${w.item.metadata.name}' in namespace '${w.item.metadata.namespace}'. The current work status is '${w.workStatus}'.`);
370104
370530
  await runWorkItem(w);
370105
- clearTimeout(timeout);
370106
370531
  }
370107
370532
  await processItem_wait();
370108
370533
  }
370109
370534
  }
370110
- /**
370111
- * Creates a timeout for a workItem
370112
- *
370113
- *
370114
- **/
370115
- function createTimeout(w) {
370116
- return setTimeout(() => {
370117
- //throw new Error('Timeout on workitem ' + w);
370118
- console.error('Timeout on workitem %O', w);
370119
- operator_src_logger.error(`The processor timed out while handling a '${w.operation}' operation for item '${w.item.kind}/${w.item.metadata.name}' in namespace '${w.item.metadata.namespace}'. The current work status is '${w.workStatus}'.`);
370120
- process.exit(1);
370121
- }, TIMEOUTS[w.operation] * 1000);
370122
- }
370123
370535
  /**
370124
370536
  * Sorts the queue based on the operation type
370125
370537
  * @param {WorkItem[]} queue - store of WorkItems
@@ -373108,11 +373520,82 @@ class TFPlanItemVersion extends TFPlanItem {
373108
373520
 
373109
373521
  /* harmony default export */ const terraform_provisioner_src_logger = (catalog_common.logger);
373110
373522
 
373523
+ ;// CONCATENATED MODULE: ../terraform_provisioner/src/process_handler.ts
373524
+
373525
+ const GRACE_PERIOD = 60 * 2; // 2 min
373526
+ const HARD_RESET_PERIOD = 10; // 10 sec
373527
+ function processHandler(processToHandle, ctl, onTimedOut) {
373528
+ let gracefulResetId;
373529
+ let hardResetId;
373530
+ let callerNotified = false;
373531
+ let timedOut = false;
373532
+ const safeKill = (signal) => {
373533
+ try {
373534
+ const sent = processToHandle.kill(signal);
373535
+ if (!sent) {
373536
+ throw new Error(`Failed to send signal ${signal} to the process`);
373537
+ }
373538
+ }
373539
+ catch (error) {
373540
+ terraform_provisioner_src_logger.error(`FATAL: timeout signal ${signal} could not be delivered to the process: ${error}`);
373541
+ if (!callerNotified) {
373542
+ ctl.processKilled(false);
373543
+ callerNotified = true;
373544
+ }
373545
+ }
373546
+ };
373547
+ const terminateId = setTimeout(() => {
373548
+ // we take control of the process
373549
+ onTimedOut();
373550
+ timedOut = true;
373551
+ // send sigInt
373552
+ terraform_provisioner_src_logger.error(`Terraform process has not exited after initial timeout of ${ctl.hardTimeout} seconds, sending SIGINT...`);
373553
+ safeKill('SIGINT');
373554
+ // grace period
373555
+ gracefulResetId = setTimeout(() => {
373556
+ terraform_provisioner_src_logger.error(`Terraform process has not exited after SIGINT grace period of ${GRACE_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD} seconds), sending SIGTERM...`);
373557
+ safeKill('SIGTERM');
373558
+ // hard reset period
373559
+ hardResetId = setTimeout(() => {
373560
+ terraform_provisioner_src_logger.error(`Terraform process has not exited after SIGTERM hard reset period of ${HARD_RESET_PERIOD} seconds (total elapsed ~${ctl.hardTimeout + GRACE_PERIOD + HARD_RESET_PERIOD} seconds), sending SIGKILL...`);
373561
+ safeKill('SIGKILL');
373562
+ setTimeout(() => {
373563
+ // we send if the process was killed or not to the caller
373564
+ if (!callerNotified) {
373565
+ ctl.processKilled(processToHandle.killed);
373566
+ callerNotified = true;
373567
+ }
373568
+ }, 10 * 1000);
373569
+ }, HARD_RESET_PERIOD * 1000);
373570
+ }, GRACE_PERIOD * 1000);
373571
+ }, ctl.hardTimeout * 1000);
373572
+ processToHandle.on('exit', () => {
373573
+ // the process has exited
373574
+ // let's clear all the timeouts
373575
+ if (terminateId) {
373576
+ clearTimeout(terminateId);
373577
+ }
373578
+ if (gracefulResetId) {
373579
+ clearTimeout(gracefulResetId);
373580
+ }
373581
+ if (hardResetId) {
373582
+ clearTimeout(hardResetId);
373583
+ }
373584
+ // we inform the caller
373585
+ // if the process exited and the timeout control has kicked-off
373586
+ if (!callerNotified && timedOut) {
373587
+ ctl.processKilled(true);
373588
+ callerNotified = true;
373589
+ }
373590
+ });
373591
+ }
373592
+
373111
373593
  ;// CONCATENATED MODULE: ../terraform_provisioner/src/utils.ts
373112
373594
 
373113
373595
 
373114
373596
 
373115
373597
 
373598
+
373116
373599
  async function utils_validate(path, secrets) {
373117
373600
  return await tfExec(path, ['validate'], secrets);
373118
373601
  }
@@ -373122,28 +373605,28 @@ async function init(path, secrets, stream) {
373122
373605
  async function initFromModule(path, source, secrets, stream) {
373123
373606
  return tfExec(path, ['init', `-from-module=${source}`], secrets, [], stream);
373124
373607
  }
373125
- async function plan(path, secrets, format, args = ['plan'], stream) {
373608
+ async function plan(path, secrets, format, args = ['plan'], stream, ctl) {
373126
373609
  terraform_provisioner_src_logger.info(`Running terraform plan with ${format} in path ${path}`);
373127
- const plan = await tfExec(path, args.concat(format === 'json' ? ['-json'] : []), secrets, ['-input=false'], stream);
373610
+ const plan = await tfExec(path, args.concat(format === 'json' ? ['-json'] : []), secrets, ['-input=false'], stream, ctl);
373128
373611
  if (format === 'json') {
373129
373612
  const tfPlan = planGet(plan);
373130
373613
  return tfPlan;
373131
373614
  }
373132
373615
  return plan;
373133
373616
  }
373134
- async function apply(path, secrets, stream) {
373617
+ async function apply(path, secrets, stream, ctl) {
373135
373618
  terraform_provisioner_src_logger.debug(`Running terraform apply in path ${path}`);
373136
- return await tfExec(path, ['apply', '-auto-approve'], secrets, ['-input=false'], stream);
373619
+ return await tfExec(path, ['apply', '-auto-approve'], secrets, ['-input=false'], stream, ctl);
373137
373620
  }
373138
- async function destroy(path, secrets, stream) {
373621
+ async function destroy(path, secrets, stream, ctl) {
373139
373622
  terraform_provisioner_src_logger.debug(`Running terraform destroy in path ${path}`);
373140
- return await tfExec(path, ['destroy', '-auto-approve'], secrets, ['-input=false'], stream);
373623
+ return await tfExec(path, ['destroy', '-auto-approve'], secrets, ['-input=false'], stream, ctl);
373141
373624
  }
373142
373625
  async function output(path, secrets) {
373143
373626
  terraform_provisioner_src_logger.debug(`Running terraform output in path ${path}`);
373144
373627
  return await tfExec(path, ['output', '-json'], secrets, []);
373145
373628
  }
373146
- async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream) {
373629
+ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream, ctl) {
373147
373630
  return new Promise((ok, ko) => {
373148
373631
  const tfProcess = (0,external_child_process_.spawn)('tofu', args.concat(extraArgs), {
373149
373632
  cwd: path,
@@ -373153,6 +373636,7 @@ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream)
373153
373636
  let flagStdoutEnd = false;
373154
373637
  let flagStderrEnd = false;
373155
373638
  let outputErrors = '';
373639
+ let processTimeout = false;
373156
373640
  tfProcess.stdout.on('data', (log) => {
373157
373641
  const line = catalog_common.io.stripAnsi(log.toString());
373158
373642
  output += line;
@@ -373173,12 +373657,21 @@ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream)
373173
373657
  });
373174
373658
  tfProcess.on('exit', async (code) => {
373175
373659
  let retryCount = 0;
373176
- while ((!flagStdoutEnd && !flagStderrEnd) || retryCount < 10) {
373660
+ while (!flagStdoutEnd && !flagStderrEnd && retryCount < 10) {
373177
373661
  retryCount++;
373178
373662
  await catalog_common.generic.sleep(500);
373179
373663
  }
373664
+ // this process has been killed/terminated
373665
+ // by timeout (not in our control)
373666
+ if (processTimeout) {
373667
+ terraform_provisioner_src_logger.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
373668
+ ko(catalog_common.generic.buildCommandExecutionError([output, outputErrors, '\n<PROCESS TIMEOUT>'].join(''), catalog_common.generic.normalizeExitCode(code), args.concat(extraArgs), {
373669
+ errorName: 'TerraformCommandError',
373670
+ label: 'Terraform command',
373671
+ }));
373672
+ return;
373673
+ }
373180
373674
  if (code !== 0) {
373181
- terraform_provisioner_src_logger.error(`Terraform output ${path}: ${output + outputErrors}`);
373182
373675
  terraform_provisioner_src_logger.error(`Terraform output ${path}: ${[output, outputErrors].join('')}`);
373183
373676
  ko(catalog_common.generic.buildCommandExecutionError([output, outputErrors].join(''), catalog_common.generic.normalizeExitCode(code), args.concat(extraArgs), {
373184
373677
  errorName: 'TerraformCommandError',
@@ -373190,6 +373683,13 @@ async function tfExec(path, args, secrets, extraArgs = ['-input=false'], stream)
373190
373683
  ok(output);
373191
373684
  }
373192
373685
  });
373686
+ if (ctl) {
373687
+ void processHandler(tfProcess, ctl, () => {
373688
+ // callback to be called by the process handler
373689
+ // we set on our flag to avoid sending our own messages
373690
+ processTimeout = true;
373691
+ });
373692
+ }
373193
373693
  });
373194
373694
  }
373195
373695
  async function configureGit(ghToken) {
@@ -373678,6 +374178,15 @@ class project_tf_TFProjectManager {
373678
374178
  }
373679
374179
  this.secrets = ctx.secrets;
373680
374180
  }
374181
+ set ctl(ctl) {
374182
+ this._ctl = ctl;
374183
+ }
374184
+ get ctl() {
374185
+ return this._ctl;
374186
+ }
374187
+ getOutput() {
374188
+ return this.tfOutput;
374189
+ }
373681
374190
  setStreamCallbacks(fnData, fnEnd, reopen = true) {
373682
374191
  if (reopen || !this.stream)
373683
374192
  this.stream = new external_stream_.PassThrough();
@@ -373686,9 +374195,6 @@ class project_tf_TFProjectManager {
373686
374195
  });
373687
374196
  this.stream.on('end', fnEnd);
373688
374197
  }
373689
- getOutput() {
373690
- return this.tfOutput;
373691
- }
373692
374198
  async build() {
373693
374199
  await this.mainTfWriter.render();
373694
374200
  this.mainTfWriter.writeToTerraformProject(external_path_.join(this.projectPath, 'firestartr-main.tf'));
@@ -373715,7 +374221,7 @@ class project_tf_TFProjectManager {
373715
374221
  await this.__init();
373716
374222
  if (format === 'json')
373717
374223
  this.tfOutput = null;
373718
- this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan'], this.stream);
374224
+ this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan'], this.stream, this.ctl);
373719
374225
  if (this.stream)
373720
374226
  this.stream.end();
373721
374227
  }
@@ -373723,17 +374229,17 @@ class project_tf_TFProjectManager {
373723
374229
  await this.__init();
373724
374230
  if (format === 'json')
373725
374231
  this.tfOutput = null;
373726
- this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan', '-destroy'], this.stream);
374232
+ this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan', '-destroy'], this.stream, this.ctl);
373727
374233
  }
373728
374234
  async apply() {
373729
374235
  await this.__init();
373730
- this.tfOutput += await apply(this.projectPath, this.secrets, this.stream);
374236
+ this.tfOutput += await apply(this.projectPath, this.secrets, this.stream, this.ctl);
373731
374237
  if (this.stream)
373732
374238
  this.stream.end();
373733
374239
  }
373734
374240
  async destroy() {
373735
374241
  await this.__init();
373736
- this.tfOutput += await destroy(this.projectPath, this.secrets, this.stream);
374242
+ this.tfOutput += await destroy(this.projectPath, this.secrets, this.stream, this.ctl);
373737
374243
  if (this.stream)
373738
374244
  this.stream.end();
373739
374245
  }
@@ -373845,6 +374351,12 @@ class TFProjectManagerRemote {
373845
374351
  }
373846
374352
  this.tfVarsJsonWriter = new WriterTfVarsJson(ctx.values, ctx.references);
373847
374353
  }
374354
+ set ctl(ctl) {
374355
+ this._ctl = ctl;
374356
+ }
374357
+ get ctl() {
374358
+ return this._ctl;
374359
+ }
373848
374360
  getOutput() {
373849
374361
  return this.tfOutput;
373850
374362
  }
@@ -373893,23 +374405,23 @@ insteadOf = https://github.com`);
373893
374405
  async plan(format) {
373894
374406
  await this.__init();
373895
374407
  if (format === 'json') {
373896
- this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan'], this.stream);
374408
+ this.tfOutput = await plan(this.projectPath, this.secrets, format, ['plan'], this.stream, this.ctl);
373897
374409
  }
373898
374410
  else {
373899
- this.tfOutput += await plan(this.projectPath, this.secrets, format, ['plan'], this.stream);
374411
+ this.tfOutput += await plan(this.projectPath, this.secrets, format, ['plan'], this.stream, this.ctl);
373900
374412
  }
373901
374413
  if (this.stream)
373902
374414
  this.stream.end();
373903
374415
  }
373904
374416
  async apply() {
373905
374417
  await this.__init();
373906
- this.tfOutput += await apply(this.projectPath, this.secrets, this.stream);
374418
+ this.tfOutput += await apply(this.projectPath, this.secrets, this.stream, this.ctl);
373907
374419
  if (this.stream)
373908
374420
  this.stream.end();
373909
374421
  }
373910
374422
  async destroy() {
373911
374423
  await this.__init();
373912
- this.tfOutput += await destroy(this.projectPath, this.secrets, this.stream);
374424
+ this.tfOutput += await destroy(this.projectPath, this.secrets, this.stream, this.ctl);
373913
374425
  if (this.stream)
373914
374426
  this.stream.end();
373915
374427
  }
@@ -373958,7 +374470,7 @@ async function run() {
373958
374470
  await execCommand(command, tfProject);
373959
374471
  }
373960
374472
  // Programatic API
373961
- async function runTerraformProvisioner(context, command = 'init', streaming) {
374473
+ async function runTerraformProvisioner(context, command = 'init', streaming, ctl) {
373962
374474
  terraform_provisioner_src_logger.info(`Running command ${command} on a ${context.type} project`);
373963
374475
  validateContext(context);
373964
374476
  let tfProject = {};
@@ -373971,6 +374483,9 @@ async function runTerraformProvisioner(context, command = 'init', streaming) {
373971
374483
  if (streaming) {
373972
374484
  tfProject.setStreamCallbacks(streaming.fnData, streaming.fnEnd);
373973
374485
  }
374486
+ if (ctl) {
374487
+ tfProject.ctl = ctl;
374488
+ }
373974
374489
  const output = await execCommand(command, tfProject);
373975
374490
  return output;
373976
374491
  }
@@ -374215,7 +374730,17 @@ async function* doPlanJSONFormat(item, op, handler, setResult = function (_r) {
374215
374730
  if (item.metadata.annotations['firestartr.dev/last-state-pr'] || false) {
374216
374731
  await addPlanStatusCheck(item.metadata.annotations['firestartr.dev/last-state-pr'], 'Terraform plan in progress...');
374217
374732
  }
374218
- const tfPlan = await runTerraformProvisioner(context, planType);
374733
+ const tfPlan = await runTerraformProvisioner(context, planType, null, {
374734
+ hardTimeout: handler.recommendedTimeout(),
374735
+ processKilled: (killed) => {
374736
+ if (killed) {
374737
+ operator_src_logger.error(`The Terraform process for item '${item.kind}/${item.metadata.name}' was killed due to a timeout.`);
374738
+ }
374739
+ else {
374740
+ operator_src_logger.error(`PANIC!!: The Terraform process for item '${item.kind}/${item.metadata.name}' could not be killed`);
374741
+ }
374742
+ },
374743
+ });
374219
374744
  if (tfPlan.summary.hasChanges()) {
374220
374745
  yield {
374221
374746
  item,
@@ -374502,7 +375027,17 @@ async function* process_operation_markedToDeletion(item, op, handler) {
374502
375027
  }
374503
375028
  const deps = await handler.resolveReferences();
374504
375029
  const context = buildProvisionerContext(item, deps);
374505
- const destroyOutput = await runTerraformProvisioner(context, 'destroy');
375030
+ const destroyOutput = await runTerraformProvisioner(context, 'destroy', null, {
375031
+ hardTimeout: handler.recommendedTimeout(),
375032
+ processKilled: (killed) => {
375033
+ if (killed) {
375034
+ operator_src_logger.error(`The Terraform process for item '${item.kind}/${item.metadata.name}' was killed due to a timeout.`);
375035
+ }
375036
+ else {
375037
+ operator_src_logger.error(`PANIC!!: The Terraform process for item '${item.kind}/${item.metadata.name}' could not be killed`);
375038
+ }
375039
+ },
375040
+ });
374506
375041
  yield {
374507
375042
  item,
374508
375043
  reason: op,
@@ -374613,7 +375148,17 @@ async function* process_operation_doApply(item, op, handler) {
374613
375148
  const deps = await handler.resolveReferences();
374614
375149
  operator_src_logger.info(`The Terraform processor is applying and assessing dependencies for item '${item.kind}/${item.metadata.name}' with dependencies: '${deps}'.`);
374615
375150
  const context = buildProvisionerContext(item, deps);
374616
- const applyOutput = await runTerraformProvisioner(context, 'apply', checkRunCtl);
375151
+ const applyOutput = await runTerraformProvisioner(context, 'apply', checkRunCtl, {
375152
+ hardTimeout: handler.recommendedTimeout(),
375153
+ processKilled: (killed) => {
375154
+ if (killed) {
375155
+ operator_src_logger.error(`The Terraform process for item '${item.kind}/${item.metadata.name}' was killed due to a timeout.`);
375156
+ }
375157
+ else {
375158
+ operator_src_logger.error(`PANIC!!: The Terraform process for item '${item.kind}/${item.metadata.name}' could not be killed`);
375159
+ }
375160
+ },
375161
+ });
374617
375162
  const terraformOutputJson = await runTerraformProvisioner(context, 'output');
374618
375163
  if (!terraformOutputJson) {
374619
375164
  throw new Error(`Terraform output is empty for ${item.kind}/${item.metadata.name}`);
@@ -376752,9 +377297,9 @@ const crs_analyzerSubcommand = {
376752
377297
  };
376753
377298
 
376754
377299
  ;// CONCATENATED MODULE: ./package.json
376755
- const package_namespaceObject = {"i8":"1.59.3"};
377300
+ const package_namespaceObject = {"i8":"1.60.0"};
376756
377301
  ;// CONCATENATED MODULE: ../../package.json
376757
- const package_namespaceObject_1 = {"i8":"1.59.3"};
377302
+ const package_namespaceObject_1 = {"i8":"1.60.0"};
376758
377303
  ;// CONCATENATED MODULE: ./src/subcommands/index.ts
376759
377304
 
376760
377305