@firestartr/cli 1.50.1-snapshot-44 → 1.51.1-snapshot-01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -346931,6 +346931,7 @@ const DEFAULT_TIME_ZONE = 'Europe/Madrid';
346931
346931
  function validateCron(cronLine, tz = DEFAULT_TIME_ZONE) {
346932
346932
  try {
346933
346933
  const interval = cron_parser_dist.CronExpressionParser.parse(cronLine, {
346934
+ // to enable the only minutes cron
346934
346935
  strict: false,
346935
346936
  tz,
346936
346937
  });
@@ -358187,6 +358188,7 @@ const GithubSchemas = [
358187
358188
  type: 'string',
358188
358189
  },
358189
358190
  },
358191
+ additionalProperties: false,
358190
358192
  required: ['enabled'],
358191
358193
  oneOf: [
358192
358194
  {
@@ -358995,14 +358997,7 @@ async function loadInitializers(claim, initializersPath = config_getPath('initia
358995
358997
  return loadedInitializers;
358996
358998
  }
358997
358999
  function loadClaimDefaults() {
358998
- try {
358999
- return catalog_common.io.fromYaml(external_fs_.readFileSync(`${config_getPath('claimsDefaults')}/claims_defaults.yaml`, 'utf-8'));
359000
- }
359001
- catch (error) {
359002
- const errMsg = `Could not read claims defaults file in path ${config_getPath('claimsDefaults')}/claims_defaults.yaml: ${error}`;
359003
- cdk8s_renderer_src_logger.error(errMsg);
359004
- throw new Error(errMsg);
359005
- }
359000
+ return catalog_common.io.fromYaml(external_fs_.readFileSync(`${config_getPath('claimsDefaults')}/claims_defaults.yaml`, 'utf-8'));
359006
359001
  }
359007
359002
  /*
359008
359003
  * Using fast-json-patch, compares a claim to its kind's defaults, then patches it.
@@ -365295,19 +365290,12 @@ function getConfigPath() {
365295
365290
  getConfigPath,
365296
365291
  });
365297
365292
 
365298
- ;// CONCATENATED MODULE: ../importer/src/logger.ts
365299
-
365300
- /* harmony default export */ const importer_src_logger = (catalog_common.logger);
365301
-
365302
365293
  ;// CONCATENATED MODULE: ../importer/src/decanter/base.ts
365303
365294
 
365304
365295
 
365305
365296
 
365306
365297
 
365307
365298
 
365308
-
365309
-
365310
-
365311
365299
  class Decanter {
365312
365300
  set github(githubInstance) {
365313
365301
  this._github = githubInstance;
@@ -365429,20 +365417,6 @@ class Decanter {
365429
365417
  adapt() {
365430
365418
  return this._adapt();
365431
365419
  }
365432
- async __loadInitializer(initDefaultPath, isAbsolute = false) {
365433
- let initPath;
365434
- try {
365435
- initPath = isAbsolute
365436
- ? initDefaultPath
365437
- : external_path_.join(getConfigPath(), 'resources', initDefaultPath);
365438
- const adapter = catalog_common.io.fromYaml(external_fs_.readFileSync(initPath, 'utf-8'));
365439
- return new InitializerDefault(adapter);
365440
- }
365441
- catch (e) {
365442
- importer_src_logger.error(`Loading ${initPath}: ${e}`);
365443
- throw new Error(`Loading ${initPath}: ${e}`);
365444
- }
365445
- }
365446
365420
  }
365447
365421
  Decanter.collectionKind = '';
365448
365422
  /* harmony default export */ const decanter_base = (Decanter);
@@ -365460,9 +365434,19 @@ class GithubDecanter extends decanter_base {
365460
365434
  }
365461
365435
  }
365462
365436
 
365437
+ ;// CONCATENATED MODULE: ../importer/src/logger.ts
365438
+
365439
+ /* harmony default export */ const importer_src_logger = (catalog_common.logger);
365440
+
365463
365441
  ;// CONCATENATED MODULE: ../importer/src/decanter/gh/github_group.ts
365464
365442
 
365465
365443
 
365444
+
365445
+
365446
+
365447
+
365448
+
365449
+
365466
365450
  class GroupGithubDecanter extends GithubDecanter {
365467
365451
  constructor() {
365468
365452
  super(...arguments);
@@ -365521,7 +365505,43 @@ class GroupGithubDecanter extends GithubDecanter {
365521
365505
  return this.__validateEqual(members, this.data.members);
365522
365506
  }
365523
365507
  async __adaptInitializerBase(_claim) {
365524
- return await this.__loadInitializer('defaults_github_group.yaml');
365508
+ let githubGroupDefaultsFilePath;
365509
+ try {
365510
+ githubGroupDefaultsFilePath = external_path_.join(getConfigPath(), 'resources', 'defaults_github_group.yaml');
365511
+ }
365512
+ catch (e) {
365513
+ importer_src_logger.warn('No config path set, using built-in defaults');
365514
+ githubGroupDefaultsFilePath = '';
365515
+ }
365516
+ let adapter;
365517
+ if (githubGroupDefaultsFilePath &&
365518
+ external_fs_.existsSync(githubGroupDefaultsFilePath)) {
365519
+ adapter = catalog_common.io.fromYaml(external_fs_.readFileSync(githubGroupDefaultsFilePath, 'utf-8'));
365520
+ }
365521
+ else {
365522
+ adapter = {
365523
+ name: 'base',
365524
+ apiVersion: 'firestartr.dev/v1',
365525
+ kind: 'FirestartrGithubGroup',
365526
+ defaultValues: {
365527
+ context: {
365528
+ backend: {
365529
+ ref: {
365530
+ kind: 'FirestartrProviderConfig',
365531
+ name: 'firestartr-terraform-state',
365532
+ },
365533
+ },
365534
+ provider: {
365535
+ ref: {
365536
+ kind: 'FirestartrProviderConfig',
365537
+ name: 'github-app',
365538
+ },
365539
+ },
365540
+ },
365541
+ },
365542
+ };
365543
+ }
365544
+ return new InitializerDefault(adapter);
365525
365545
  }
365526
365546
  __validateKind(cr) {
365527
365547
  return true;
@@ -365617,6 +365637,12 @@ applyCollectionMixins(GroupCollectionGithubDecanter);
365617
365637
  ;// CONCATENATED MODULE: ../importer/src/decanter/gh/github_member.ts
365618
365638
 
365619
365639
 
365640
+
365641
+
365642
+
365643
+
365644
+
365645
+
365620
365646
  class MemberGithubDecanter extends GithubDecanter {
365621
365647
  constructor() {
365622
365648
  super(...arguments);
@@ -365654,7 +365680,43 @@ class MemberGithubDecanter extends GithubDecanter {
365654
365680
  });
365655
365681
  }
365656
365682
  async __adaptInitializerBase(_claim) {
365657
- return await this.__loadInitializer('defaults_github_membership.yaml');
365683
+ let githubMemberDefaultsFilePath;
365684
+ try {
365685
+ githubMemberDefaultsFilePath = external_path_.join(getConfigPath(), 'resources', 'defaults_github_membership.yaml');
365686
+ }
365687
+ catch (e) {
365688
+ importer_src_logger.warn('No config path set, using built-in defaults');
365689
+ githubMemberDefaultsFilePath = '';
365690
+ }
365691
+ let adapter;
365692
+ if (githubMemberDefaultsFilePath &&
365693
+ external_fs_.existsSync(githubMemberDefaultsFilePath)) {
365694
+ adapter = catalog_common.io.fromYaml(external_fs_.readFileSync(githubMemberDefaultsFilePath, 'utf-8'));
365695
+ }
365696
+ else {
365697
+ adapter = {
365698
+ name: 'base',
365699
+ apiVersion: 'firestartr.dev/v1',
365700
+ kind: 'FirestartrGithubMembership',
365701
+ defaultValues: {
365702
+ context: {
365703
+ backend: {
365704
+ ref: {
365705
+ kind: 'FirestartrProviderConfig',
365706
+ name: 'firestartr-terraform-state',
365707
+ },
365708
+ },
365709
+ provider: {
365710
+ ref: {
365711
+ kind: 'FirestartrProviderConfig',
365712
+ name: 'github-app',
365713
+ },
365714
+ },
365715
+ },
365716
+ },
365717
+ };
365718
+ }
365719
+ return new InitializerDefault(adapter);
365658
365720
  }
365659
365721
  }
365660
365722
 
@@ -365687,6 +365749,11 @@ applyCollectionMixins(MemberCollectionGithubDecanter);
365687
365749
 
365688
365750
 
365689
365751
 
365752
+
365753
+
365754
+
365755
+
365756
+
365690
365757
  const TYPE_MAP = {
365691
365758
  User: 'user',
365692
365759
  Team: 'group',
@@ -365944,7 +366011,74 @@ class RepoGithubDecanter extends GithubDecanter {
365944
366011
  return null;
365945
366012
  }
365946
366013
  async __adaptInitializerBase(_claim) {
365947
- return await this.__loadInitializer('defaults_github_repository.yaml');
366014
+ let githubRepoDefaultsFilePath;
366015
+ try {
366016
+ githubRepoDefaultsFilePath = external_path_.join(getConfigPath(), 'resources', 'defaults_github_repository.yaml');
366017
+ }
366018
+ catch (e) {
366019
+ importer_src_logger.warn('No config path set, using built-in defaults');
366020
+ githubRepoDefaultsFilePath = '';
366021
+ }
366022
+ let adapter;
366023
+ if (githubRepoDefaultsFilePath &&
366024
+ external_fs_.existsSync(githubRepoDefaultsFilePath)) {
366025
+ adapter = catalog_common.io.fromYaml(external_fs_.readFileSync(githubRepoDefaultsFilePath, 'utf-8'));
366026
+ }
366027
+ else {
366028
+ adapter = {
366029
+ name: 'base',
366030
+ apiVersion: 'firestartr.dev/v1',
366031
+ kind: 'FirestartrGithubRepository',
366032
+ defaultValues: {
366033
+ context: {
366034
+ backend: {
366035
+ ref: {
366036
+ kind: 'FirestartrProviderConfig',
366037
+ name: 'firestartr-terraform-state',
366038
+ },
366039
+ },
366040
+ provider: {
366041
+ ref: {
366042
+ kind: 'FirestartrProviderConfig',
366043
+ name: 'github-app',
366044
+ },
366045
+ },
366046
+ },
366047
+ name: this.data.repoDetails.name,
366048
+ description: this.data.repoDetails.description,
366049
+ org: this.org,
366050
+ firestartr: {
366051
+ technology: { stack: 'none', version: 'none' },
366052
+ },
366053
+ repo: {
366054
+ description: this.data.repoDetails.description,
366055
+ allowMergeCommit: this.data.repoDetails.allow_merge_commit,
366056
+ allowSquashMerge: this.data.repoDetails.allow_squash_merge,
366057
+ allowRebaseMerge: this.data.repoDetails.allow_rebase_merge,
366058
+ allowAutoMerge: this.data.repoDetails.allow_auto_merge,
366059
+ deleteBranchOnMerge: this.data.repoDetails.delete_branch_on_merge,
366060
+ autoInit: true,
366061
+ archiveOnDestroy: true,
366062
+ allowUpdateBranch: this.data.repoDetails.allow_update_branch,
366063
+ hasIssues: this.data.repoDetails.has_issues,
366064
+ visibility: this.data.repoDetails.visibility,
366065
+ defaultBranch: this.data.repoDetails.default_branch,
366066
+ },
366067
+ permissions: [],
366068
+ actions: {
366069
+ oidc: this.data.oidc.use_default
366070
+ ? undefined
366071
+ : {
366072
+ useDefault: this.data.oidc.use_default,
366073
+ includeClaimKeys: this.data.oidc.include_claim_keys
366074
+ ? this.data.oidc.include_claim_keys
366075
+ : [],
366076
+ },
366077
+ },
366078
+ },
366079
+ };
366080
+ }
366081
+ return new InitializerDefault(adapter);
365948
366082
  }
365949
366083
  async __adaptOverriderRepo(_claim) {
365950
366084
  return new GithubRepositoryOverrider();
@@ -366188,17 +366322,22 @@ function compileReg(value) {
366188
366322
  });
366189
366323
 
366190
366324
 
366325
+
366191
366326
  // const MAP_COLLECTION_KIND_CR_KIND: any = {
366192
366327
  // gh-members: 'FirestartrGithubMembership',
366193
366328
  // gh-group: 'FirestartrGithubGroup',
366194
366329
  // gh-repo: 'FirestartrGithubRepository',
366195
366330
  // }
366196
- async function runImporter(force, skipPlan, claimsPath, crsPath, configPath, claimsDefaultsPath, org, filters, provider = AllowedProviders.all) {
366331
+ async function runImporter(force, generateDefaults, skipPlan, claimsPath, crsPath, configPath, claimsDefaultsPath, org, filters, provider = AllowedProviders.all) {
366197
366332
  configureProvider(provider);
366198
366333
  let generatedFilters = [];
366199
366334
  //gh-repo,REGEXP=.*vite.*
366200
366335
  cdk8s_renderer.setPath('claimsDefaults', claimsDefaultsPath);
366201
366336
  generatedFilters = buildFilters(filters, force, crsPath, generatedFilters);
366337
+ if (generateDefaults) {
366338
+ generateClaimsDefaults(org, claimsDefaultsPath);
366339
+ generateDefaultsFn(org, configPath);
366340
+ }
366202
366341
  await importGithubGitopsRepository(org, skipPlan, claimsPath, crsPath, configPath, generatedFilters);
366203
366342
  }
366204
366343
  function buildFilters(filters, force, crsPath, generatedFilters) {
@@ -366234,6 +366373,97 @@ function createSkipFilters(filters) {
366234
366373
  }
366235
366374
  return filters;
366236
366375
  }
366376
+ function generateDefaultsFn(org, defaultsPath) {
366377
+ generateDefaultsForGithubGroups(org, defaultsPath);
366378
+ generateDefaultsForGithubRepos(org, defaultsPath);
366379
+ generateDefaultsForGithubRepos(org, defaultsPath);
366380
+ }
366381
+ function generateDefaultsForGithubGroups(org, defaultsPath) {
366382
+ const defaultGroups = {
366383
+ name: 'group_base',
366384
+ apiVersion: 'firestartr.dev/v1',
366385
+ kind: 'FirestartrGithubGroup',
366386
+ defaultValues: {
366387
+ org: org,
366388
+ },
366389
+ };
366390
+ catalog_common.io.writeYamlFile('defaults_github_group', defaultGroups, defaultsPath);
366391
+ }
366392
+ function generateDefaultsForGithubRepos(org, defaultsPath) {
366393
+ const defaultRepos = {
366394
+ name: 'repo_base',
366395
+ apiVersion: 'firestartr.dev/v1',
366396
+ kind: 'FirestartrGithubRepository',
366397
+ defaultValues: {
366398
+ firestartr: {
366399
+ technology: {
366400
+ stack: 'none',
366401
+ version: 'none',
366402
+ },
366403
+ },
366404
+ repo: {
366405
+ allowAutoMerge: true,
366406
+ codeowners: ' - ',
366407
+ allowMergeCommit: true,
366408
+ allowSquashMerge: true,
366409
+ allowRebaseMerge: true,
366410
+ deleteBranchOnMerge: true,
366411
+ autoInit: true,
366412
+ archiveOnDestroy: true,
366413
+ allowUpdateBranch: true,
366414
+ hasIssues: true,
366415
+ },
366416
+ },
366417
+ };
366418
+ catalog_common.io.writeYamlFile('defaults_github_repository', defaultRepos, defaultsPath);
366419
+ }
366420
+ function generateClaimsDefaults(org, defaultsPath) {
366421
+ const defaultClaims = {
366422
+ ComponentClaim: {
366423
+ version: '1.0',
366424
+ type: 'service',
366425
+ lifecycle: 'production',
366426
+ system: 'system:firestartr-test-system',
366427
+ maintainedBy: [],
366428
+ platformOwner: `group:${org}-all`,
366429
+ providers: {
366430
+ github: {
366431
+ org: org,
366432
+ branchStrategy: {
366433
+ name: 'trunkBasedDevelopment',
366434
+ defaultBranch: 'main',
366435
+ },
366436
+ orgPermissions: 'none',
366437
+ visibility: 'private',
366438
+ technology: {
366439
+ stack: 'none',
366440
+ version: 'none',
366441
+ },
366442
+ features: [],
366443
+ },
366444
+ },
366445
+ },
366446
+ GroupClaim: {
366447
+ providers: {
366448
+ github: {
366449
+ org: org,
366450
+ privacy: 'closed',
366451
+ },
366452
+ },
366453
+ },
366454
+ SystemClaim: {
366455
+ providers: {
366456
+ catalog: null,
366457
+ },
366458
+ },
366459
+ DomainClaim: {
366460
+ providers: {
366461
+ catalog: null,
366462
+ },
366463
+ },
366464
+ };
366465
+ catalog_common.io.writeYamlFile('claims_defaults', defaultClaims, defaultsPath);
366466
+ }
366237
366467
 
366238
366468
  ;// CONCATENATED MODULE: ./src/subcommands/importer-subcommands.ts
366239
366469
 
@@ -366242,6 +366472,7 @@ const importSubcommand = {
366242
366472
  requiredEnv: [],
366243
366473
  subparameters: [
366244
366474
  { name: 'force', type: Boolean },
366475
+ { name: 'generateDefaults', type: Boolean },
366245
366476
  { name: 'skipPlan', type: Boolean },
366246
366477
  { name: 'claims', type: String },
366247
366478
  { name: 'crs', type: String },
@@ -366252,7 +366483,7 @@ const importSubcommand = {
366252
366483
  ],
366253
366484
  run: async (options) => {
366254
366485
  console.table(options);
366255
- await runImporter(options.force, options.skipPlan, options.claims, options.crs, options.config, options.claimsDefaults, options.org, options.filters);
366486
+ await runImporter(options.force, options.generateDefaults, options.skipPlan, options.claims, options.crs, options.config, options.claimsDefaults, options.org, options.filters);
366256
366487
  },
366257
366488
  };
366258
366489
 
@@ -367109,6 +367340,28 @@ async function needsProvisioningOnCreate(cr) {
367109
367340
  operator_src_logger.debug(`Skipping the provisioning process for custom resource '${cr.kind}/${cr.metadata.name}' because its current state is not handled.`);
367110
367341
  return false;
367111
367342
  }
367343
+ async function updateSyncTransition(itemPath, reason, lastSyncTime, nextSyncTime, message, status) {
367344
+ operator_src_logger.info(`The item at '${itemPath}' transitioned to a new SYNCHRONIZED condition of '${status}'. The reason for the change is '${reason}' with the message: '${message}'.`);
367345
+ const k8sItem = await getItemByItemPath(itemPath);
367346
+ if (!('status' in k8sItem))
367347
+ k8sItem.status = {};
367348
+ if (!('conditions' in k8sItem.status))
367349
+ k8sItem.status.conditions = [];
367350
+ let conditionObject = getRelevantCondition(k8sItem.status.conditions, 'SYNCHRONIZED');
367351
+ conditionObject = {
367352
+ ...conditionObject,
367353
+ reason,
367354
+ status,
367355
+ message,
367356
+ observedGeneration: k8sItem.metadata.generation,
367357
+ lastSyncTime,
367358
+ lastUpdateTime: new Date().toJSON(),
367359
+ nextSyncTime,
367360
+ };
367361
+ k8sItem.status.conditions = updateConditionByType(k8sItem.status.conditions, 'SYNCHRONIZED', conditionObject);
367362
+ const itemParameters = itemPath.split('/');
367363
+ await writeStatus(itemParameters[1], itemParameters[0], k8sItem);
367364
+ }
367112
367365
  async function updateTransition(itemPath, reason, type, statusValue, message = '', updateStatusOnly = false) {
367113
367366
  operator_src_logger.info(`The item at '${itemPath}' transitioned to a new status of '${statusValue}' (type: '${type}'). The reason for the change is '${reason}' with the message: '${message}'. This was a status-only update: '${updateStatusOnly}'.`);
367114
367367
  const k8sItem = await getItemByItemPath(itemPath);
@@ -367169,12 +367422,115 @@ function updateConditionByType(conditionList, type, newCondition) {
367169
367422
  return conditionList;
367170
367423
  }
367171
367424
 
367172
- ;// CONCATENATED MODULE: ../operator/src/syncer.ts
367425
+ ;// CONCATENATED MODULE: ../operator/src/syncCtl.ts
367426
+ // Machinery for syncing
367427
+
367428
+
367173
367429
 
367174
367430
 
367175
- const syncWatchers = {};
367176
- const FORCE_REVISION_TIME = 60 * 1000;
367177
367431
  const DEFAULT_REVISION_TIME = '1m';
367432
+ async function createWatcherForItem(itemPath, itemCR) {
367433
+ const item = itemCR ?? await getItemByItemPath(itemPath);
367434
+ const syncStatus = await getSyncStatus(itemPath, item);
367435
+ let nextTimeoutInMS = syncStatus.nextTimeoutInMS;
367436
+ // we have lapsed last interval
367437
+ // we calculate from the lastSyncTime
367438
+ if (syncStatus.intervalLapsed) {
367439
+ operator_src_logger.debug(`Next sync interval have been lapsed for ${itemPath}`);
367440
+ if (syncStatus.syncMode === 'Period') {
367441
+ operator_src_logger.debug(`Next sync interval have been lapsed for ${itemPath} the sync will start now`);
367442
+ nextTimeoutInMS = -1;
367443
+ }
367444
+ }
367445
+ const watcher = {
367446
+ itemPath,
367447
+ lastRevision: setTimeout(() => {
367448
+ operator_src_logger.debug(`Item ${itemPath} needs revision`);
367449
+ watcher.needsRevision = true;
367450
+ }, nextTimeoutInMS),
367451
+ needsRevision: false,
367452
+ };
367453
+ return watcher;
367454
+ }
367455
+ async function destroyWatcherForItem(watcher) {
367456
+ clearTimeout(watcher.lastRevision);
367457
+ operator_src_logger.debug(`Disabled SyncWatcher for ${watcher.itemPath}`);
367458
+ }
367459
+ async function getSyncSpecs(itemPath, itemCR) {
367460
+ const item = itemCR ?? await getItemByItemPath(itemPath);
367461
+ return {
367462
+ item,
367463
+ syncable: item.metadata.annotations &&
367464
+ item.metadata.annotations['firestartr.dev/sync-enabled'] &&
367465
+ item.metadata.annotations['firestartr.dev/sync-enabled'] === 'true',
367466
+ period: item.metadata.annotations['firestartr.dev/sync-period'] ||
367467
+ DEFAULT_REVISION_TIME,
367468
+ schedule: item.metadata.annotations['firestartr.dev/sync-schedule'] || false,
367469
+ scheduleTZ: item.metadata.annotations['firestartr.dev/sync-schedule-timezone'] ||
367470
+ 'Europe/Madrid',
367471
+ };
367472
+ }
367473
+ async function getSyncStatus(itemPath, itemCR) {
367474
+ const item = itemCR ?? await getItemByItemPath(itemPath);
367475
+ const syncCondition = getConditionByType(item.status?.conditions ?? [], 'SYNCHRONIZED');
367476
+ // no sync condition present
367477
+ if (!syncCondition) {
367478
+ return {
367479
+ syncStatusPresent: false,
367480
+ };
367481
+ }
367482
+ else {
367483
+ const nextSyncDate = new Date(syncCondition.nextSyncTime);
367484
+ const isLapsed = Date.now() >= nextSyncDate.getTime();
367485
+ const mode = (await getSyncSpecs(itemPath, item)).schedule
367486
+ ? 'Scheduled'
367487
+ : 'Period';
367488
+ return {
367489
+ itemPath,
367490
+ syncMode: mode,
367491
+ conditions: [syncCondition],
367492
+ syncStatusPresent: true,
367493
+ nextTimeoutInMS: isLapsed ? -1 : nextSyncDate.getTime() - Date.now(),
367494
+ intervalLapsed: isLapsed,
367495
+ };
367496
+ }
367497
+ }
367498
+ async function setSyncStatus(itemPath, reason, status, message) {
367499
+ const item = await getItemByItemPath(itemPath);
367500
+ const machinery = assessSyncCalculationMachinery(item);
367501
+ const syncStatus = await machinery(item, reason, status, message);
367502
+ syncStatus.itemPath = itemPath;
367503
+ syncStatus.syncStatusPresent = true;
367504
+ operator_src_logger.info(`Setting sync status for ${itemPath}: ${JSON.stringify(syncStatus)}`);
367505
+ const syncTransition = syncStatus.conditions[0];
367506
+ await updateSyncTransition(itemPath, syncTransition.reason, syncTransition.lastSyncTime, syncTransition.nextSyncTime, syncTransition.message, syncTransition.status);
367507
+ return syncStatus;
367508
+ }
367509
+ function assessSyncCalculationMachinery(item) {
367510
+ if (item.metadata.annotations['firestartr.dev/sync-schedule'] ?? false) {
367511
+ return processScheduledSync;
367512
+ }
367513
+ else {
367514
+ return processPeriodSync;
367515
+ }
367516
+ }
367517
+ async function processPeriodSync(item, reason, status, message) {
367518
+ const period = item.metadata.annotations['firestartr.dev/sync-period'];
367519
+ const periodMS = helperCalculateRevisionTime(period);
367520
+ return {
367521
+ syncMode: 'Period',
367522
+ conditions: [
367523
+ {
367524
+ reason,
367525
+ type: 'SYNCHRONIZED',
367526
+ message,
367527
+ status,
367528
+ lastSyncTime: new Date().toISOString(),
367529
+ nextSyncTime: new Date(Date.now() + periodMS).toISOString(),
367530
+ },
367531
+ ],
367532
+ };
367533
+ }
367178
367534
  function helperCalculateRevisionTime(period) {
367179
367535
  const [_, scalar, dimension] = period.split(/(\d+)/);
367180
367536
  const multiplier = dimension === 's'
@@ -367188,24 +367544,50 @@ function helperCalculateRevisionTime(period) {
367188
367544
  : 1;
367189
367545
  return Number(scalar) * multiplier * 1000;
367190
367546
  }
367547
+ async function processScheduledSync(item, reason, status, message) {
367548
+ const nextPeriod = catalog_common.cron.getCronNextInterval(item.metadata.annotations['firestartr.dev/sync-schedule'], item.metadata.annotations['firestartr.dev/sync-schedule-timezone'] ||
367549
+ undefined);
367550
+ const nextPeriodDate = new Date(nextPeriod);
367551
+ return {
367552
+ syncMode: 'Scheduled',
367553
+ conditions: [
367554
+ {
367555
+ reason,
367556
+ type: 'SYNCHRONIZED',
367557
+ message,
367558
+ status,
367559
+ lastSyncTime: new Date().toISOString(),
367560
+ nextSyncTime: nextPeriodDate.toISOString(),
367561
+ },
367562
+ ],
367563
+ };
367564
+ }
367565
+
367566
+ ;// CONCATENATED MODULE: ../operator/src/syncer.ts
367567
+
367568
+
367569
+
367570
+ const syncWatchers = {};
367571
+ const FORCE_REVISION_TIME = (/* unused pure expression or super */ null && (60 * 1000));
367191
367572
  async function syncer(enqueue) {
367192
367573
  // fork
367193
367574
  void loop(enqueue);
367194
367575
  return {
367195
367576
  addItem(itemPath) {
367196
367577
  operator_src_logger.info(`Added item of path '${itemPath}' for synchronization`);
367197
- void itemIsSyncable(itemPath).then((itemSyncInfo) => {
367578
+ getSyncSpecs(itemPath)
367579
+ .then(async (itemSyncInfo) => {
367198
367580
  if (!itemSyncInfo.syncable) {
367199
367581
  return;
367200
367582
  }
367201
- syncWatchers[itemPath] = {
367202
- itemPath,
367203
- lastRevision: setInterval(() => {
367204
- syncWatchers[itemPath].needsRevision = true;
367205
- }, helperCalculateRevisionTime(itemSyncInfo.period)),
367206
- needsRevision: false,
367207
- };
367583
+ const syncCtl = await getSyncStatus(itemPath, itemSyncInfo.item);
367584
+ syncWatchers[itemPath] = await createWatcherForItem(itemPath, itemSyncInfo.item);
367208
367585
  operator_src_logger.info(`Configured synchronization for item at path '${itemPath}'`);
367586
+ operator_src_logger.debug(`Sync information for '${itemPath}': ${JSON.stringify({ ...itemSyncInfo, item: null }, null)}`);
367587
+ })
367588
+ .catch((err) => {
367589
+ operator_src_logger.error(`Error on sync [add item]: ${err}`);
367590
+ throw `Error on sync [add item]: ${err}`;
367209
367591
  });
367210
367592
  },
367211
367593
  updateItem(itemPath) {
@@ -367214,27 +367596,24 @@ async function syncer(enqueue) {
367214
367596
  // return
367215
367597
  //}
367216
367598
  operator_src_logger.debug(`Updated item of path '${itemPath}' during synchronization`);
367217
- void itemIsSyncable(itemPath).then((itemSyncInfo) => {
367218
- if (!itemSyncInfo.syncable) {
367219
- if (syncWatchers[itemPath]) {
367220
- clearInterval(syncWatchers[itemPath].lastRevision);
367221
- delete syncWatchers[itemPath];
367222
- operator_src_logger.info(`Removed item of path '${itemPath}' from synchronization`);
367223
- }
367599
+ getSyncSpecs(itemPath)
367600
+ .then(async (itemSyncInfo) => {
367601
+ if (syncWatchers[itemPath]) {
367602
+ await destroyWatcherForItem(syncWatchers[itemPath]);
367603
+ delete syncWatchers[itemPath];
367224
367604
  }
367225
- else {
367226
- if (itemSyncInfo.syncable && syncWatchers[itemPath]) {
367227
- clearInterval(syncWatchers[itemPath].lastRevision);
367228
- }
367229
- syncWatchers[itemPath] = {
367230
- itemPath,
367231
- lastRevision: setInterval(() => {
367232
- syncWatchers[itemPath].needsRevision = true;
367233
- }, helperCalculateRevisionTime(itemSyncInfo.period)),
367234
- needsRevision: false,
367235
- };
367236
- operator_src_logger.debug(`Configured synchronization for item at path '${itemPath}' with watcher '${syncWatchers[itemPath]}'`);
367605
+ // we need to chedk if the item is not syncable anymore
367606
+ if (!itemSyncInfo.syncable) {
367607
+ operator_src_logger.info(`Removed item of path '${itemPath}' from synchronization`);
367608
+ return;
367237
367609
  }
367610
+ // if it is syncable we need to recalculate everything
367611
+ syncWatchers[itemPath] = await createWatcherForItem(itemPath);
367612
+ operator_src_logger.info(`Configured synchronization for item at path '${itemPath}' with watcher`);
367613
+ })
367614
+ .catch((err) => {
367615
+ operator_src_logger.error(`Error on sync [updateItem]: ${err}`);
367616
+ throw `Error on sync [updateItem]: ${err}`;
367238
367617
  });
367239
367618
  },
367240
367619
  deleteItem(itemPath) {
@@ -367242,10 +367621,15 @@ async function syncer(enqueue) {
367242
367621
  operator_src_logger.debug(`Ignored deletion attempt for item at path '${itemPath}' as it was not found during synchronization`);
367243
367622
  return;
367244
367623
  }
367245
- operator_src_logger.debug(`Deleted item of path '${itemPath}' during synchronization`);
367246
- clearInterval(syncWatchers[itemPath].lastRevision);
367247
- delete syncWatchers[itemPath];
367248
- operator_src_logger.debug(`Successfully deleted item at path '${itemPath}' during synchronization`);
367624
+ destroyWatcherForItem(syncWatchers[itemPath])
367625
+ .then(() => {
367626
+ operator_src_logger.debug(`Deleted item of path '${itemPath}' during synchronization`);
367627
+ delete syncWatchers[itemPath];
367628
+ })
367629
+ .catch((err) => {
367630
+ operator_src_logger.error(`Error deleting item of path ${itemPath} for synchronization: ${err}`);
367631
+ throw `Error deleting item of path ${itemPath} for synchronization: ${err}`;
367632
+ });
367249
367633
  },
367250
367634
  };
367251
367635
  }
@@ -367255,23 +367639,14 @@ async function loop(enqueueIfNeeded) {
367255
367639
  const needRevisionItems = Object.values(syncWatchers).filter((watcher) => watcher.needsRevision);
367256
367640
  for (const watcher of needRevisionItems) {
367257
367641
  const item = await getItemIfNeededSync(watcher);
367642
+ operator_src_logger.debug(`Item needs revision ${watcher.itemPath}`);
367258
367643
  if (item !== null) {
367259
367644
  enqueueIfNeeded(item);
367260
- watcher.needsRevision = false;
367261
367645
  }
367646
+ watcher.needsRevision = false;
367262
367647
  }
367263
367648
  }
367264
367649
  }
367265
- async function itemIsSyncable(itemPath) {
367266
- const item = await getItemByItemPath(itemPath);
367267
- return {
367268
- syncable: item.metadata.annotations &&
367269
- item.metadata.annotations['firestartr.dev/sync-enabled'] &&
367270
- item.metadata.annotations['firestartr.dev/sync-enabled'] === 'true',
367271
- period: item.metadata.annotations['firestartr.dev/sync-period'] ||
367272
- DEFAULT_REVISION_TIME,
367273
- };
367274
- }
367275
367650
  async function getItemIfNeededSync(watcher) {
367276
367651
  const item = await getItemByItemPath(watcher.itemPath);
367277
367652
  const isProvisioning = item.status?.conditions?.find((condition) => condition.type === 'PROVISIONING' && condition.status === 'True');
@@ -367280,13 +367655,7 @@ async function getItemIfNeededSync(watcher) {
367280
367655
  const isDeleting = item.status?.conditions?.find((condition) => condition.type === 'DELETING' && condition.status === 'True');
367281
367656
  if (isDeleting)
367282
367657
  return null;
367283
- const synchronizedCondition = item.status?.conditions?.find((condition) => condition.type === 'SYNCHRONIZED' && condition.status === 'True');
367284
- if (!synchronizedCondition)
367285
- return item;
367286
- const lastSync = new Date(synchronizedCondition.lastUpdateTime).getTime();
367287
- if (lastSync <= Date.now() - FORCE_REVISION_TIME)
367288
- return item;
367289
- return null;
367658
+ return item;
367290
367659
  }
367291
367660
  function fWait(segs = 1) {
367292
367661
  return new Promise((ok) => {
@@ -367542,6 +367911,7 @@ var WorkStatus;
367542
367911
 
367543
367912
 
367544
367913
 
367914
+
367545
367915
  const kindsWithFinalizer = [
367546
367916
  'FirestartrTerraformWorkspace',
367547
367917
  'FirestartrGithubGroup',
@@ -367661,14 +368031,17 @@ function enqueue(pluralKind, workItem, queue, compute, syncCtl, retryCtl) {
367661
368031
  success: () => retryCtl.successReconciling(informer_itemPath(pluralKind, workItem.item)),
367662
368032
  };
367663
368033
  workItem.process = async function* (item, operation, handler) {
367664
- for await (const transition of compute(item, operation, handler)) {
367665
- yield transition;
367666
- }
367667
- if (operation === OperationType.RENAMED ||
368034
+ const needsUpdateSyncContidions = operation === OperationType.RENAMED ||
367668
368035
  operation === OperationType.UPDATED ||
367669
368036
  operation === OperationType.SYNC ||
367670
368037
  operation === OperationType.CREATED ||
367671
- operation === OperationType.RETRY) {
368038
+ operation === OperationType.RETRY;
368039
+ await setSyncStatus(workItem.handler.itemPath(), operation, 'False', 'Sync process started');
368040
+ for await (const transition of compute(item, operation, handler)) {
368041
+ yield transition;
368042
+ }
368043
+ if (needsUpdateSyncContidions) {
368044
+ await setSyncStatus(workItem.handler.itemPath(), operation, operation === OperationType.SYNC ? 'True' : 'False', 'Sync process finished');
367672
368045
  syncCtl.updateItem(informer_itemPath(pluralKind, item));
367673
368046
  }
367674
368047
  else {
@@ -371794,13 +372167,6 @@ function isDestroyRetry(item) {
371794
372167
  return false;
371795
372168
  }
371796
372169
  async function* process_operation_sync(item, op, handler, syncPolicy, generalPolicy) {
371797
- yield {
371798
- item,
371799
- reason: op,
371800
- type: 'SYNCHRONIZED',
371801
- status: 'False',
371802
- message: 'Sync process started',
371803
- };
371804
372170
  if (!syncPolicy) {
371805
372171
  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}'.`);
371806
372172
  yield* doPlanJSONFormat(item, op, handler);
@@ -686,6 +686,7 @@ declare const schemas: {
686
686
  type: string;
687
687
  };
688
688
  };
689
+ additionalProperties: boolean;
689
690
  required: string[];
690
691
  oneOf: ({
691
692
  required: string[];
@@ -41,6 +41,7 @@ export declare const TerraformSchemas: {
41
41
  type: string;
42
42
  };
43
43
  };
44
+ additionalProperties: boolean;
44
45
  required: string[];
45
46
  oneOf: ({
46
47
  required: string[];
@@ -41,6 +41,7 @@ declare const _default: {
41
41
  type: string;
42
42
  };
43
43
  };
44
+ additionalProperties: boolean;
44
45
  required: string[];
45
46
  oneOf: ({
46
47
  required: string[];
@@ -6,4 +6,4 @@ declare const _default: {
6
6
  };
7
7
  export default _default;
8
8
  import { AllowedProviders } from 'cdk8s_renderer';
9
- export declare function runImporter(force: boolean, skipPlan: boolean, claimsPath: string, crsPath: string, configPath: string, claimsDefaultsPath: string, org: string, filters: string[], provider?: AllowedProviders): Promise<void>;
9
+ export declare function runImporter(force: boolean, generateDefaults: boolean, skipPlan: boolean, claimsPath: string, crsPath: string, configPath: string, claimsDefaultsPath: string, org: string, filters: string[], provider?: AllowedProviders): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { ImportInitializer, UUIDInitializer, NameNormalizer, InitializerClaimRef, InitializerDefault } from 'cdk8s_renderer';
1
+ import { ImportInitializer, UUIDInitializer, NameNormalizer, InitializerClaimRef } from 'cdk8s_renderer';
2
2
  export default class Decanter {
3
3
  data: any;
4
4
  claimKind: string | undefined;
@@ -78,5 +78,4 @@ export default class Decanter {
78
78
  normalizers: NameNormalizer[];
79
79
  };
80
80
  }>;
81
- __loadInitializer(initDefaultPath: string, isAbsolute?: boolean): Promise<InitializerDefault>;
82
81
  }
@@ -1,8 +1,9 @@
1
1
  import { GithubDecanter } from './base';
2
+ import { InitializerDefault } from 'cdk8s_renderer';
2
3
  export default class MemberGithubDecanter extends GithubDecanter {
3
4
  claimKind: string;
4
5
  __decantStart(): void;
5
6
  __gatherRoleInOrg(): Promise<void>;
6
7
  __decantProviders(): void;
7
- __adaptInitializerBase(_claim: any): Promise<import("../../../../cdk8s_renderer").InitializerDefault>;
8
+ __adaptInitializerBase(_claim: any): Promise<InitializerDefault>;
8
9
  }
@@ -1,2 +1,4 @@
1
1
  export declare function needsProvisioningOnCreate(cr: any): Promise<boolean>;
2
+ export declare function updateSyncTransition(itemPath: string, reason: string, lastSyncTime: string, nextSyncTime: string, message: string, status: string): Promise<void>;
2
3
  export declare function updateTransition(itemPath: string, reason: string, type: string, statusValue: string, message?: string, updateStatusOnly?: boolean): Promise<void>;
4
+ export declare function getConditionByType(conditionList: Array<any>, type: string): any;
@@ -0,0 +1,26 @@
1
+ export type Condition = {
2
+ type: string;
3
+ status: 'True' | 'False' | 'Unknown';
4
+ reason: string;
5
+ message: string;
6
+ lastSyncTime?: string;
7
+ nextSyncTime?: string;
8
+ };
9
+ export type SyncStatus = {
10
+ itemPath?: string;
11
+ conditions?: Condition[];
12
+ nextTimeoutInMS?: number;
13
+ syncStatusPresent?: boolean;
14
+ intervalLapsed?: boolean;
15
+ syncMode?: 'Scheduled' | 'Period';
16
+ };
17
+ export type SyncWatcher = {
18
+ itemPath: string;
19
+ lastRevision: any;
20
+ needsRevision: boolean;
21
+ };
22
+ export declare function createWatcherForItem(itemPath: string, itemCR?: any): Promise<SyncWatcher>;
23
+ export declare function destroyWatcherForItem(watcher: SyncWatcher): Promise<void>;
24
+ export declare function getSyncSpecs(itemPath: string, itemCR?: any): Promise<any>;
25
+ export declare function getSyncStatus(itemPath: string, itemCR?: any): Promise<SyncStatus>;
26
+ export declare function setSyncStatus(itemPath: string, reason: string, status: 'True' | 'False' | 'Unknown', message: string): Promise<SyncStatus>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestartr/cli",
3
- "version": "1.50.1-snapshot-44",
3
+ "version": "1.51.1-snapshot-01",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",