@camunda/ccma-shared-types 7.4.0 → 7.6.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.
- package/dist/_tests/constants/custom-generation.const.spec.d.ts +1 -0
- package/dist/_tests/utils/jvmOptions.spec.d.ts +1 -0
- package/dist/approvals/policy.js +2 -1
- package/dist/approvals/policy.js.map +2 -2
- package/dist/approvals/use-cases.const.d.ts +3 -0
- package/dist/approvals/use-cases.const.js +9 -1
- package/dist/approvals/use-cases.const.js.map +2 -2
- package/dist/constants/custom-generation.const.d.ts +28 -0
- package/dist/constants/custom-generation.const.js +67 -0
- package/dist/constants/custom-generation.const.js.map +7 -0
- package/dist/dtos/ApprovalJob.dto.d.ts +13 -0
- package/dist/dtos/ApprovalJob.dto.js.map +1 -1
- package/dist/dtos/ControlV2.dto.d.ts +8 -0
- package/dist/dtos/SalesPlan.dto.d.ts +5 -0
- package/dist/dtos/SalesPlan.dto.js +8 -0
- package/dist/dtos/SalesPlan.dto.js.map +2 -2
- package/dist/index.d.ts +6 -3
- package/dist/index.js +46 -0
- package/dist/index.js.map +2 -2
- package/dist/permissions/console.permissions.d.ts +7 -0
- package/dist/permissions/console.permissions.js +7 -0
- package/dist/permissions/console.permissions.js.map +2 -2
- package/dist/types/ClusterPlanTypeCategory.type.d.ts +1 -1
- package/dist/types/ClusterTtl.type.d.ts +27 -0
- package/dist/types/ClusterTtl.type.js.map +1 -1
- package/dist/types/ClusterUsageMetrics.type.d.ts +22 -0
- package/dist/utils/jvmOptions.d.ts +80 -0
- package/dist/utils/jvmOptions.js +120 -0
- package/dist/utils/jvmOptions.js.map +7 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/permissions/console.permissions.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type { Roles } from '../types/Roles.js'\n\nexport namespace ConsolePermissions {\n export const MULTICLUSTER_ADMIN = 'cmca'\n\n export const CHANNELS_AND_GENERATIONS_ADMIN_DELETE_ALL_CLUSTERS = 'cmgda'\n export const CHANNELS_AND_GENERATIONS_ADMIN_SEE = 'cmgas'\n export const CHANNELS_AND_GENERATIONS_ADMIN = 'cmga'\n export const CHANNELS_AND_GENERATIONS_ADMIN_PATCH_EXISTING_CHANNEL = 'cmgap'\n export const CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE = 'cmgam'\n export const CHANNELS_AND_GENERATIONS_MIGRATE = 'cmgm'\n export const ALL_CHANNELS_AND_GENERATIONS: string[] = [\n CHANNELS_AND_GENERATIONS_ADMIN_SEE,\n CHANNELS_AND_GENERATIONS_ADMIN,\n CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE,\n ]\n export const CLUSTERS_READALLCLUSTERINFO = 'ccrai'\n export const CLUSTERS_DELETE_CLUSTER = 'ccda'\n export const CLUSTERS_CAN_MOVE_TO_OTHER_ORG = 'ccmoo'\n export const CLUSTERS_CAN_SEND_TO_SLEEP = 'ccsts'\n export const CLUSTERS_CAN_CREATE_INTERNAL_BACKUP = 'cccib'\n export const CLUSTERS_CAN_UPDATE_CLUSTERPLANTYPE = 'ccucp'\n export const CLUSTERS_CAN_UPDATE_GENERATION = 'ccug'\n export const CLUSTERS_CAN_UPDATE_GENERATION_YOLO = 'ccugy'\n export const CLUSTERS_CAN_UPDATE_OPTIONAL_TELEMETRY = 'ccuot'\n\n export const CLUSTER_PLAN_SEE_ALL = 'ccpa'\n export const CLUSTER_PLAN_CREATE = 'ccpc'\n export const CLUSTER_PLAN_DELETE = 'ccpd'\n\n export const CLUSTER_PLAN_TYPE_CREATE = 'cptc'\n export const CLUSTER_PLAN_TYPE_MODIFY = 'cptm'\n export const CLUSTER_PLAN_TYPE_DELETE = 'cptd'\n export const CLUSTER_PLAN_TYPE_FORCE_DELETE = 'cptfd'\n\n export const CLUSTER_PLAN_MIGRATE = 'ccpm'\n export const CLUSTER_PLAN_CAN_DELETE_ALL_CLUSTERS_OF_PLAN = 'ccpda'\n export const CLUSTER_PLAN_CAN_MODIFY = 'ccpmo'\n\n export const M2M_UPDATE_CRD = 'cmuc'\n export const M2M_SIGNUP = 'cms'\n export const M2M_TRIGGER_ALERT = 'cmta'\n export const M2M_DELETE_ORG_CLUSTERS = 'cmdoc'\n export const M2M_UPDATE_ORG_CLUSTERS = 'cmuoc'\n export const M2M_ADD_CLUSTER_USAGE_METRICS = 'cmacm'\n export const M2M_SEND_SSE_EVENT = 'cmsse'\n export const M2M_EXTERNAL_INTERNAL_CLIENT = 'cmeic'\n export const M2M_FETCH_MIGRATION_DATA = 'cmfmd'\n export const M2M_MANAGE_GENERATION_UPGRADE_PATH = 'cmmgup'\n\n /**\n * The one m2m permission of control-backend. It opens every route of\n * `api/admin/approvals` in accounts-backend and in console-backend, which\n * control-backend calls when a four-eyes request has the approvals that it\n * needs.\n *\n * One permission for all of them, by a decision of the team: one grant at\n * Auth0 for the whole approval surface of control-backend. A route that\n * reads it runs an action that people already approved, so the permission\n * goes to the m2m application of control-backend and to no other client.\n *\n * It is NOT the permission that a Camundi needs. A person needs the\n * permission of the action, such as `CLUSTERS_CAN_MOVE_TO_OTHER_ORG`, and\n * control-backend asks for that one before it accepts an approval.\n */\n export const M2M_CONTROL_APPROVALS = 'ctam'\n /**\n * Stands in for the permission of EVERY approval use case of\n * control-backend, for a person who tests the approval flow.\n *\n * A holder can open, approve, reject and run each use case, including one\n * that a later change adds, with no grant of its own permission. The four-eyes\n * rule still holds: nobody approves their own request.\n *\n * It is a permission of a PERSON. No machine route reads it, because a token\n * that a Camundi can get must not run an action with no approval. It goes to\n * no role at Auth0: a person with access to the tenant grants it by hand, and\n * only on a stage where the approval flow is under test.\n */\n export const APPROVALS_ALL_USE_CASES = 'caauc'\n export const CLUSTER_CREATE_ON_BEHALF = 'cccob'\n export const FEATURE_NEW_HOME = 'cfnh'\n export const FEATURE_TEMPLATE_PICKER = 'cftp'\n export const USER_SETTINGS = 'cus'\n export const CLUSTERS_CAN_OVERRIDE_ENV_VARS = 'ccoev'\n export const CLUSTERS_CAN_CREATE_MODIFICATION_CONFIG = 'ccccmc'\n\n export const DEBUG = 'cdbg'\n export const GOD_TRIGGER_CRONS = 'gtc'\n\n export const RELEASE_TRAIN_PUBLISH = 'crtp'\n\n export const APICLIENT_READ = 'capr'\n export const APICLIENT_DELETE = 'capd'\n\n export interface Features {\n apiClient: {\n read: boolean\n delete: boolean\n }\n multiCluster: {\n admin: boolean\n }\n multiGen: {\n admin: {\n see: boolean\n modify: boolean\n patchExistingChannel: boolean\n migrate: boolean\n deleteAllClustersOfGeneration: boolean\n }\n releaseTrain: {\n publish: boolean\n }\n }\n clusters: {\n canReadAllClusterInfo: boolean\n canDeleteAllClusters: boolean\n canMoveToOtherOrg: boolean\n createOnBehalf: boolean\n canSendToSleep: boolean\n canCreateInternalBackup: boolean\n canUpdateClusterPlanType: boolean\n canOverrideEnvVars: boolean\n canCreateModificationConfig: boolean\n canUpgradeGeneration: boolean\n canUpgradeGenerationYolo: boolean\n canUpdateOptionalTelemetry: boolean\n }\n clusterPlan: {\n seeAll: boolean\n create: boolean\n delete: boolean\n type: {\n create: boolean\n modify: boolean\n delete: boolean\n forceDelete: boolean\n }\n migrate: boolean\n deleteAllClustersOfPlan: boolean\n modify: boolean\n }\n features: {\n newHome: boolean\n templatePicker: boolean\n userSettings: boolean\n debug: boolean\n }\n m2m: {\n updateCrd: boolean\n signup: boolean\n triggerAlert: boolean\n deleteOrgClusters: boolean\n updateOrgClusters: boolean\n addUsageMetrics: boolean\n sendSseEvent: boolean\n external: {\n internalClient: boolean\n }\n fetchMigrationData: boolean\n manageGenerationUpgradePath: boolean\n /** Every route of `api/admin/approvals`. See `M2M_CONTROL_APPROVALS`. */\n approvals: boolean\n }\n }\n\n export function createEmptyFeatures(): Features {\n return {\n apiClient: {\n read: false,\n delete: false,\n },\n multiCluster: { admin: false },\n multiGen: {\n admin: {\n migrate: false,\n modify: false,\n patchExistingChannel: false,\n see: false,\n deleteAllClustersOfGeneration: false,\n },\n releaseTrain: {\n publish: false,\n },\n },\n clusters: {\n canReadAllClusterInfo: false,\n canDeleteAllClusters: false,\n canMoveToOtherOrg: false,\n createOnBehalf: false,\n canSendToSleep: false,\n canCreateInternalBackup: false,\n canUpdateClusterPlanType: false,\n canOverrideEnvVars: false,\n canCreateModificationConfig: false,\n canUpgradeGeneration: false,\n canUpgradeGenerationYolo: false,\n canUpdateOptionalTelemetry: false,\n },\n clusterPlan: {\n seeAll: false,\n create: false,\n delete: false,\n type: {\n create: false,\n modify: false,\n delete: false,\n forceDelete: false,\n },\n migrate: false,\n deleteAllClustersOfPlan: false,\n modify: false,\n },\n features: {\n newHome: false,\n templatePicker: false,\n userSettings: false,\n debug: false,\n },\n m2m: {\n updateCrd: false,\n signup: false,\n triggerAlert: false,\n deleteOrgClusters: false,\n updateOrgClusters: false,\n addUsageMetrics: false,\n sendSseEvent: false,\n external: {\n internalClient: false,\n },\n fetchMigrationData: false,\n manageGenerationUpgradePath: false,\n approvals: false,\n },\n }\n }\n\n export const PermissionsAtAuth0: Array<{\n value: string\n description: string\n initialRoles: Roles[]\n }> = [\n {\n value: MULTICLUSTER_ADMIN,\n description: 'can create and delete k8s clusters',\n initialRoles: ['console:admin'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_SEE,\n description: 'can go to the admin section for MultiGen, but no touch!',\n initialRoles: [\n 'console:admin',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n 'console:C8UpdateEnforcer',\n ],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN,\n description: 'can create channels, generations and combine them',\n initialRoles: ['console:admin', 'console:C8ReleaseManager'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_PATCH_EXISTING_CHANNEL,\n description: 'can modify existing channels and combine them',\n initialRoles: [\n 'console:admin',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n ],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE,\n description:\n 'can migrate clusters of generations to supported other generations',\n initialRoles: ['console:admin', 'console:C8UpdateEnforcer'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_DELETE_ALL_CLUSTERS,\n description: 'can delete all clusters of a generation',\n initialRoles: ['console:admin'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_MIGRATE,\n description:\n 'can migrate owned clusters of generations to supported other generations',\n initialRoles: [],\n },\n {\n value: CLUSTERS_READALLCLUSTERINFO,\n description: 'can read clusterInfo for all clusters',\n initialRoles: [\n 'accounts:read',\n 'accounts:onboard',\n 'accounts:orgCreator',\n 'accounts:admin',\n 'accounts:editSalesPlans',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'console:admin',\n 'accounts:trialExtender',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTERS_DELETE_CLUSTER,\n description: 'can delete clusters in all orgs',\n initialRoles: ['accounts:admin'],\n },\n {\n value: CLUSTERS_CAN_MOVE_TO_OTHER_ORG,\n description: 'can move a cluster to another org the user is part of',\n // CSMs, TAMs and consultants move a cluster to another org for a\n // customer, thus the capability goes to `console:clusterMover`. The\n // population that holds the role lives in the Camundi permission\n // rules, not in the name of the role.\n initialRoles: ['console:admin', 'console:clusterMover'],\n },\n {\n value: CLUSTER_PLAN_SEE_ALL,\n description: 'can see all ClusterPlans',\n initialRoles: [\n 'console:admin',\n 'accounts:read',\n 'accounts:orgCreator',\n 'accounts:admin',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'accounts:onboard',\n 'accounts:editSalesPlans',\n 'accounts:trialExtender',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTER_PLAN_CREATE,\n description: 'can create ClusterPlans',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_DELETE,\n description: 'can delete ClusterPlans',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_CREATE,\n description: 'can create ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_DELETE,\n description: 'can delete ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_FORCE_DELETE,\n description: 'can delete ClusterPlanTypes',\n initialRoles: ['console:god'],\n },\n {\n value: CLUSTER_PLAN_TYPE_MODIFY,\n description: 'can modify ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_MIGRATE,\n description: 'can migrate Clusters from one plan to another',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_CAN_DELETE_ALL_CLUSTERS_OF_PLAN,\n description: 'can delete all clusters of a plan',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_CREATE_ON_BEHALF,\n description:\n 'enables accounts to create clusters on signup (not a user permission)',\n initialRoles: [],\n },\n {\n value: M2M_SIGNUP,\n description: 'allows to signal to Console new user signups',\n initialRoles: [],\n },\n { value: M2M_UPDATE_CRD, description: 'may update crds', initialRoles: [] },\n {\n value: M2M_TRIGGER_ALERT,\n description: 'allows Infra and Operate to trigger alerts',\n initialRoles: [],\n },\n {\n value: M2M_DELETE_ORG_CLUSTERS,\n description:\n 'allows trigger console to delete all clusters of an Organization',\n initialRoles: [],\n },\n {\n value: M2M_UPDATE_ORG_CLUSTERS,\n description: 'allows to update clusters of an Organization',\n initialRoles: [],\n },\n {\n value: M2M_ADD_CLUSTER_USAGE_METRICS,\n description: 'allows to trigger update of value metrics',\n initialRoles: [],\n },\n {\n value: M2M_SEND_SSE_EVENT,\n description: 'allows to trigger SSE events',\n initialRoles: [],\n },\n {\n value: M2M_EXTERNAL_INTERNAL_CLIENT,\n description: 'allows to fetch internal clients',\n initialRoles: [],\n },\n // `initialRoles` is empty, and it must stay empty. A machine client holds\n // a grant on its Auth0 application, and never a role. An entry here with a\n // role would give the permission to every person in that role.\n {\n value: M2M_CONTROL_APPROVALS,\n description:\n 'm2m can run the approved actions of control-backend in accounts and console',\n initialRoles: [],\n },\n // No role, on purpose. This permission opens every approval use case, so\n // a person with access to the tenant grants it by hand, for testing.\n {\n value: APPROVALS_ALL_USE_CASES,\n description:\n 'can open, approve, reject and run every approval use case of Control (for testing)',\n initialRoles: [],\n },\n {\n value: M2M_FETCH_MIGRATION_DATA,\n description: 'allows to fetch migration data',\n initialRoles: [],\n },\n {\n value: M2M_MANAGE_GENERATION_UPGRADE_PATH,\n description:\n 'allows to manage upgrade paths for generations via external API',\n initialRoles: [],\n },\n {\n value: FEATURE_NEW_HOME,\n description: 'allows users to see new home',\n initialRoles: ['console:admin'],\n },\n {\n value: USER_SETTINGS,\n description: 'allows users to see user settings',\n initialRoles: ['console:admin', 'betatester:true'],\n },\n {\n value: FEATURE_TEMPLATE_PICKER,\n description: 'allows users to see template picker',\n initialRoles: ['console:admin', 'betatester:true'],\n },\n {\n value: CLUSTERS_CAN_SEND_TO_SLEEP,\n description: 'may send a cluster to sleep and wake up',\n initialRoles: [\n 'console:admin',\n 'accounts:admin',\n 'console:operationsEngineer',\n ],\n },\n {\n value: CLUSTERS_CAN_CREATE_INTERNAL_BACKUP,\n description: 'may create and delete internal (incident) backups',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: DEBUG,\n description: 'can see additional debugging tools',\n initialRoles: ['console:admin:readonly', 'console:admin'],\n },\n {\n value: CLUSTERS_CAN_OVERRIDE_ENV_VARS,\n description:\n 'can set Env Vars on cluster level that override all ClusterPlan Env Vars',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: CLUSTERS_CAN_CREATE_MODIFICATION_CONFIG,\n description: 'can create cluster modification configs',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: CLUSTERS_CAN_UPDATE_CLUSTERPLANTYPE,\n description: 'can update clusterplantype of a running cluster',\n initialRoles: [\n 'console:admin',\n 'accounts:onboard',\n 'console:operationsEngineer',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTERS_CAN_UPDATE_GENERATION,\n description: 'can update generation of a running cluster',\n initialRoles: [\n 'console:admin',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n ],\n },\n {\n value: CLUSTERS_CAN_UPDATE_GENERATION_YOLO,\n description:\n 'can update generation of a running cluster even if the generation is not reachable',\n initialRoles: ['console:god'],\n },\n {\n value: CLUSTERS_CAN_UPDATE_OPTIONAL_TELEMETRY,\n description:\n 'can enable or disable optional product telemetry for a cluster',\n // A customer asks their CSM or TAM to switch the category off, thus the\n // capability goes to `console:optionalTelemetryManager`. The population\n // that holds the role lives in the Camundi permission rules, not in the\n // name of the role. The console team keeps the permission, to help when\n // a change does not take effect.\n initialRoles: ['console:admin', 'console:optionalTelemetryManager'],\n },\n {\n value: CLUSTER_PLAN_CAN_MODIFY,\n description: 'can trigger modifications of a clusterplan',\n initialRoles: ['console:admin', 'console:clusterPlanManager'],\n },\n {\n value: RELEASE_TRAIN_PUBLISH,\n description: 'can publish new generations via the release train endpoint',\n initialRoles: ['console:admin', 'console:C8ReleaseManager'],\n },\n {\n value: APICLIENT_READ,\n description: 'can read API Clients Names of Organizations',\n initialRoles: ['accounts:read', 'accounts:orgCreator'],\n },\n {\n value: APICLIENT_DELETE,\n description: 'can read API Clients Names of Organizations',\n initialRoles: ['accounts:god'],\n },\n ]\n}\n"],
|
|
5
|
-
"mappings": "AAQO,IAAU;AAAA,CAAV,CAAUA,wBAAV;AACE,EAAMA,oBAAA,qBAAqB;AAE3B,EAAMA,oBAAA,qDAAqD;AAC3D,EAAMA,oBAAA,qCAAqC;AAC3C,EAAMA,oBAAA,iCAAiC;AACvC,EAAMA,oBAAA,wDAAwD;AAC9D,EAAMA,oBAAA,yCAAyC;AAC/C,EAAMA,oBAAA,mCAAmC;AACzC,EAAMA,oBAAA,+BAAyC;AAAA,IACpDA,oBAAA;AAAA,IACAA,oBAAA;AAAA,IACAA,oBAAA;AAAA,EACF;AACO,EAAMA,oBAAA,8BAA8B;AACpC,EAAMA,oBAAA,0BAA0B;AAChC,EAAMA,oBAAA,iCAAiC;AACvC,EAAMA,oBAAA,6BAA6B;AACnC,EAAMA,oBAAA,sCAAsC;AAC5C,EAAMA,oBAAA,sCAAsC;AAC5C,EAAMA,oBAAA,iCAAiC;AACvC,EAAMA,oBAAA,sCAAsC;AAC5C,EAAMA,oBAAA,yCAAyC;AAE/C,EAAMA,oBAAA,uBAAuB;AAC7B,EAAMA,oBAAA,sBAAsB;AAC5B,EAAMA,oBAAA,sBAAsB;AAE5B,EAAMA,oBAAA,2BAA2B;AACjC,EAAMA,oBAAA,2BAA2B;AACjC,EAAMA,oBAAA,2BAA2B;AACjC,EAAMA,oBAAA,iCAAiC;AAEvC,EAAMA,oBAAA,uBAAuB;AAC7B,EAAMA,oBAAA,+CAA+C;AACrD,EAAMA,oBAAA,0BAA0B;AAEhC,EAAMA,oBAAA,iBAAiB;AACvB,EAAMA,oBAAA,aAAa;AACnB,EAAMA,oBAAA,oBAAoB;AAC1B,EAAMA,oBAAA,0BAA0B;AAChC,EAAMA,oBAAA,0BAA0B;AAChC,EAAMA,oBAAA,gCAAgC;AACtC,EAAMA,oBAAA,qBAAqB;AAC3B,EAAMA,oBAAA,+BAA+B;AACrC,EAAMA,oBAAA,2BAA2B;AACjC,EAAMA,oBAAA,qCAAqC;AAiB3C,EAAMA,oBAAA,wBAAwB;
|
|
4
|
+
"sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type { Roles } from '../types/Roles.js'\n\nexport namespace ConsolePermissions {\n export const MULTICLUSTER_ADMIN = 'cmca'\n\n export const CHANNELS_AND_GENERATIONS_ADMIN_DELETE_ALL_CLUSTERS = 'cmgda'\n export const CHANNELS_AND_GENERATIONS_ADMIN_SEE = 'cmgas'\n export const CHANNELS_AND_GENERATIONS_ADMIN = 'cmga'\n export const CHANNELS_AND_GENERATIONS_ADMIN_PATCH_EXISTING_CHANNEL = 'cmgap'\n export const CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE = 'cmgam'\n export const CHANNELS_AND_GENERATIONS_MIGRATE = 'cmgm'\n export const ALL_CHANNELS_AND_GENERATIONS: string[] = [\n CHANNELS_AND_GENERATIONS_ADMIN_SEE,\n CHANNELS_AND_GENERATIONS_ADMIN,\n CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE,\n ]\n export const CLUSTERS_READALLCLUSTERINFO = 'ccrai'\n export const CLUSTERS_DELETE_CLUSTER = 'ccda'\n export const CLUSTERS_CAN_MOVE_TO_OTHER_ORG = 'ccmoo'\n export const CLUSTERS_CAN_SEND_TO_SLEEP = 'ccsts'\n export const CLUSTERS_CAN_CREATE_INTERNAL_BACKUP = 'cccib'\n export const CLUSTERS_CAN_UPDATE_CLUSTERPLANTYPE = 'ccucp'\n export const CLUSTERS_CAN_UPDATE_GENERATION = 'ccug'\n export const CLUSTERS_CAN_UPDATE_GENERATION_YOLO = 'ccugy'\n export const CLUSTERS_CAN_UPDATE_OPTIONAL_TELEMETRY = 'ccuot'\n\n export const CLUSTER_PLAN_SEE_ALL = 'ccpa'\n export const CLUSTER_PLAN_CREATE = 'ccpc'\n export const CLUSTER_PLAN_DELETE = 'ccpd'\n\n export const CLUSTER_PLAN_TYPE_CREATE = 'cptc'\n export const CLUSTER_PLAN_TYPE_MODIFY = 'cptm'\n export const CLUSTER_PLAN_TYPE_DELETE = 'cptd'\n export const CLUSTER_PLAN_TYPE_FORCE_DELETE = 'cptfd'\n\n export const CLUSTER_PLAN_MIGRATE = 'ccpm'\n export const CLUSTER_PLAN_CAN_DELETE_ALL_CLUSTERS_OF_PLAN = 'ccpda'\n export const CLUSTER_PLAN_CAN_MODIFY = 'ccpmo'\n\n export const M2M_UPDATE_CRD = 'cmuc'\n export const M2M_SIGNUP = 'cms'\n export const M2M_TRIGGER_ALERT = 'cmta'\n export const M2M_DELETE_ORG_CLUSTERS = 'cmdoc'\n export const M2M_UPDATE_ORG_CLUSTERS = 'cmuoc'\n export const M2M_ADD_CLUSTER_USAGE_METRICS = 'cmacm'\n export const M2M_SEND_SSE_EVENT = 'cmsse'\n export const M2M_EXTERNAL_INTERNAL_CLIENT = 'cmeic'\n export const M2M_FETCH_MIGRATION_DATA = 'cmfmd'\n export const M2M_MANAGE_GENERATION_UPGRADE_PATH = 'cmmgup'\n\n /**\n * The one m2m permission of control-backend. It opens every route of\n * `api/admin/approvals` in accounts-backend and in console-backend, which\n * control-backend calls when a four-eyes request has the approvals that it\n * needs.\n *\n * One permission for all of them, by a decision of the team: one grant at\n * Auth0 for the whole approval surface of control-backend. A route that\n * reads it runs an action that people already approved, so the permission\n * goes to the m2m application of control-backend and to no other client.\n *\n * It is NOT the permission that a Camundi needs. A person needs the\n * permission of the action, such as `CLUSTERS_CAN_MOVE_TO_OTHER_ORG`, and\n * control-backend asks for that one before it accepts an approval.\n */\n export const M2M_CONTROL_APPROVALS = 'ctam'\n /**\n * Lets the delete cron of console-backend open a `cluster-ttl-deletion`\n * request in control-backend. That request needs no approval, so the\n * permission goes to the m2m application of console-backend and to no other\n * client.\n */\n export const M2M_CLUSTER_TTL_DELETION = 'cmctd'\n /**\n * Stands in for the permission of EVERY approval use case of\n * control-backend, for a person who tests the approval flow.\n *\n * A holder can open, approve, reject and run each use case, including one\n * that a later change adds, with no grant of its own permission. The four-eyes\n * rule still holds: nobody approves their own request.\n *\n * It is a permission of a PERSON. No machine route reads it, because a token\n * that a Camundi can get must not run an action with no approval. It goes to\n * no role at Auth0: a person with access to the tenant grants it by hand, and\n * only on a stage where the approval flow is under test.\n */\n export const APPROVALS_ALL_USE_CASES = 'caauc'\n export const CLUSTER_CREATE_ON_BEHALF = 'cccob'\n export const FEATURE_NEW_HOME = 'cfnh'\n export const FEATURE_TEMPLATE_PICKER = 'cftp'\n export const USER_SETTINGS = 'cus'\n export const CLUSTERS_CAN_OVERRIDE_ENV_VARS = 'ccoev'\n export const CLUSTERS_CAN_CREATE_MODIFICATION_CONFIG = 'ccccmc'\n\n export const DEBUG = 'cdbg'\n export const GOD_TRIGGER_CRONS = 'gtc'\n\n export const RELEASE_TRAIN_PUBLISH = 'crtp'\n\n export const APICLIENT_READ = 'capr'\n export const APICLIENT_DELETE = 'capd'\n\n export interface Features {\n apiClient: {\n read: boolean\n delete: boolean\n }\n multiCluster: {\n admin: boolean\n }\n multiGen: {\n admin: {\n see: boolean\n modify: boolean\n patchExistingChannel: boolean\n migrate: boolean\n deleteAllClustersOfGeneration: boolean\n }\n releaseTrain: {\n publish: boolean\n }\n }\n clusters: {\n canReadAllClusterInfo: boolean\n canDeleteAllClusters: boolean\n canMoveToOtherOrg: boolean\n createOnBehalf: boolean\n canSendToSleep: boolean\n canCreateInternalBackup: boolean\n canUpdateClusterPlanType: boolean\n canOverrideEnvVars: boolean\n canCreateModificationConfig: boolean\n canUpgradeGeneration: boolean\n canUpgradeGenerationYolo: boolean\n canUpdateOptionalTelemetry: boolean\n }\n clusterPlan: {\n seeAll: boolean\n create: boolean\n delete: boolean\n type: {\n create: boolean\n modify: boolean\n delete: boolean\n forceDelete: boolean\n }\n migrate: boolean\n deleteAllClustersOfPlan: boolean\n modify: boolean\n }\n features: {\n newHome: boolean\n templatePicker: boolean\n userSettings: boolean\n debug: boolean\n }\n m2m: {\n updateCrd: boolean\n signup: boolean\n triggerAlert: boolean\n deleteOrgClusters: boolean\n updateOrgClusters: boolean\n addUsageMetrics: boolean\n sendSseEvent: boolean\n external: {\n internalClient: boolean\n }\n fetchMigrationData: boolean\n manageGenerationUpgradePath: boolean\n /** Every route of `api/admin/approvals`. See `M2M_CONTROL_APPROVALS`. */\n approvals: boolean\n }\n }\n\n export function createEmptyFeatures(): Features {\n return {\n apiClient: {\n read: false,\n delete: false,\n },\n multiCluster: { admin: false },\n multiGen: {\n admin: {\n migrate: false,\n modify: false,\n patchExistingChannel: false,\n see: false,\n deleteAllClustersOfGeneration: false,\n },\n releaseTrain: {\n publish: false,\n },\n },\n clusters: {\n canReadAllClusterInfo: false,\n canDeleteAllClusters: false,\n canMoveToOtherOrg: false,\n createOnBehalf: false,\n canSendToSleep: false,\n canCreateInternalBackup: false,\n canUpdateClusterPlanType: false,\n canOverrideEnvVars: false,\n canCreateModificationConfig: false,\n canUpgradeGeneration: false,\n canUpgradeGenerationYolo: false,\n canUpdateOptionalTelemetry: false,\n },\n clusterPlan: {\n seeAll: false,\n create: false,\n delete: false,\n type: {\n create: false,\n modify: false,\n delete: false,\n forceDelete: false,\n },\n migrate: false,\n deleteAllClustersOfPlan: false,\n modify: false,\n },\n features: {\n newHome: false,\n templatePicker: false,\n userSettings: false,\n debug: false,\n },\n m2m: {\n updateCrd: false,\n signup: false,\n triggerAlert: false,\n deleteOrgClusters: false,\n updateOrgClusters: false,\n addUsageMetrics: false,\n sendSseEvent: false,\n external: {\n internalClient: false,\n },\n fetchMigrationData: false,\n manageGenerationUpgradePath: false,\n approvals: false,\n },\n }\n }\n\n export const PermissionsAtAuth0: Array<{\n value: string\n description: string\n initialRoles: Roles[]\n }> = [\n {\n value: MULTICLUSTER_ADMIN,\n description: 'can create and delete k8s clusters',\n initialRoles: ['console:admin'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_SEE,\n description: 'can go to the admin section for MultiGen, but no touch!',\n initialRoles: [\n 'console:admin',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n 'console:C8UpdateEnforcer',\n ],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN,\n description: 'can create channels, generations and combine them',\n initialRoles: ['console:admin', 'console:C8ReleaseManager'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_PATCH_EXISTING_CHANNEL,\n description: 'can modify existing channels and combine them',\n initialRoles: [\n 'console:admin',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n ],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_MIGRATE,\n description:\n 'can migrate clusters of generations to supported other generations',\n initialRoles: ['console:admin', 'console:C8UpdateEnforcer'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_ADMIN_DELETE_ALL_CLUSTERS,\n description: 'can delete all clusters of a generation',\n initialRoles: ['console:admin'],\n },\n {\n value: CHANNELS_AND_GENERATIONS_MIGRATE,\n description:\n 'can migrate owned clusters of generations to supported other generations',\n initialRoles: [],\n },\n {\n value: CLUSTERS_READALLCLUSTERINFO,\n description: 'can read clusterInfo for all clusters',\n initialRoles: [\n 'accounts:read',\n 'accounts:onboard',\n 'accounts:orgCreator',\n 'accounts:admin',\n 'accounts:editSalesPlans',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'console:admin',\n 'accounts:trialExtender',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTERS_DELETE_CLUSTER,\n description: 'can delete clusters in all orgs',\n initialRoles: ['accounts:admin'],\n },\n {\n value: CLUSTERS_CAN_MOVE_TO_OTHER_ORG,\n description: 'can move a cluster to another org the user is part of',\n // CSMs, TAMs and consultants move a cluster to another org for a\n // customer, thus the capability goes to `console:clusterMover`. The\n // population that holds the role lives in the Camundi permission\n // rules, not in the name of the role.\n initialRoles: ['console:admin', 'console:clusterMover'],\n },\n {\n value: CLUSTER_PLAN_SEE_ALL,\n description: 'can see all ClusterPlans',\n initialRoles: [\n 'console:admin',\n 'accounts:read',\n 'accounts:orgCreator',\n 'accounts:admin',\n 'console:admin:readonly',\n 'support:agent',\n 'supersupport:agent',\n 'accounts:onboard',\n 'accounts:editSalesPlans',\n 'accounts:trialExtender',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTER_PLAN_CREATE,\n description: 'can create ClusterPlans',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_DELETE,\n description: 'can delete ClusterPlans',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_CREATE,\n description: 'can create ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_DELETE,\n description: 'can delete ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_TYPE_FORCE_DELETE,\n description: 'can delete ClusterPlanTypes',\n initialRoles: ['console:god'],\n },\n {\n value: CLUSTER_PLAN_TYPE_MODIFY,\n description: 'can modify ClusterPlanTypes',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_MIGRATE,\n description: 'can migrate Clusters from one plan to another',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_PLAN_CAN_DELETE_ALL_CLUSTERS_OF_PLAN,\n description: 'can delete all clusters of a plan',\n initialRoles: ['console:admin'],\n },\n {\n value: CLUSTER_CREATE_ON_BEHALF,\n description:\n 'enables accounts to create clusters on signup (not a user permission)',\n initialRoles: [],\n },\n {\n value: M2M_SIGNUP,\n description: 'allows to signal to Console new user signups',\n initialRoles: [],\n },\n { value: M2M_UPDATE_CRD, description: 'may update crds', initialRoles: [] },\n {\n value: M2M_TRIGGER_ALERT,\n description: 'allows Infra and Operate to trigger alerts',\n initialRoles: [],\n },\n {\n value: M2M_DELETE_ORG_CLUSTERS,\n description:\n 'allows trigger console to delete all clusters of an Organization',\n initialRoles: [],\n },\n {\n value: M2M_UPDATE_ORG_CLUSTERS,\n description: 'allows to update clusters of an Organization',\n initialRoles: [],\n },\n {\n value: M2M_ADD_CLUSTER_USAGE_METRICS,\n description: 'allows to trigger update of value metrics',\n initialRoles: [],\n },\n {\n value: M2M_SEND_SSE_EVENT,\n description: 'allows to trigger SSE events',\n initialRoles: [],\n },\n {\n value: M2M_EXTERNAL_INTERNAL_CLIENT,\n description: 'allows to fetch internal clients',\n initialRoles: [],\n },\n // `initialRoles` is empty, and it must stay empty. A machine client holds\n // a grant on its Auth0 application, and never a role. An entry here with a\n // role would give the permission to every person in that role.\n {\n value: M2M_CONTROL_APPROVALS,\n description:\n 'm2m can run the approved actions of control-backend in accounts and console',\n initialRoles: [],\n },\n // No role: a machine holds a grant on its application. See the note above.\n {\n value: M2M_CLUSTER_TTL_DELETION,\n description:\n 'm2m can open the request of control-backend that deletes a cluster whose TTL ran out',\n initialRoles: [],\n },\n // No role, on purpose. This permission opens every approval use case, so\n // a person with access to the tenant grants it by hand, for testing.\n {\n value: APPROVALS_ALL_USE_CASES,\n description:\n 'can open, approve, reject and run every approval use case of Control (for testing)',\n initialRoles: [],\n },\n {\n value: M2M_FETCH_MIGRATION_DATA,\n description: 'allows to fetch migration data',\n initialRoles: [],\n },\n {\n value: M2M_MANAGE_GENERATION_UPGRADE_PATH,\n description:\n 'allows to manage upgrade paths for generations via external API',\n initialRoles: [],\n },\n {\n value: FEATURE_NEW_HOME,\n description: 'allows users to see new home',\n initialRoles: ['console:admin'],\n },\n {\n value: USER_SETTINGS,\n description: 'allows users to see user settings',\n initialRoles: ['console:admin', 'betatester:true'],\n },\n {\n value: FEATURE_TEMPLATE_PICKER,\n description: 'allows users to see template picker',\n initialRoles: ['console:admin', 'betatester:true'],\n },\n {\n value: CLUSTERS_CAN_SEND_TO_SLEEP,\n description: 'may send a cluster to sleep and wake up',\n initialRoles: [\n 'console:admin',\n 'accounts:admin',\n 'console:operationsEngineer',\n ],\n },\n {\n value: CLUSTERS_CAN_CREATE_INTERNAL_BACKUP,\n description: 'may create and delete internal (incident) backups',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: DEBUG,\n description: 'can see additional debugging tools',\n initialRoles: ['console:admin:readonly', 'console:admin'],\n },\n {\n value: CLUSTERS_CAN_OVERRIDE_ENV_VARS,\n description:\n 'can set Env Vars on cluster level that override all ClusterPlan Env Vars',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: CLUSTERS_CAN_CREATE_MODIFICATION_CONFIG,\n description: 'can create cluster modification configs',\n initialRoles: ['console:admin', 'console:operationsEngineer'],\n },\n {\n value: CLUSTERS_CAN_UPDATE_CLUSTERPLANTYPE,\n description: 'can update clusterplantype of a running cluster',\n initialRoles: [\n 'console:admin',\n 'accounts:onboard',\n 'console:operationsEngineer',\n 'accounts:enterpriseAdmin',\n ],\n },\n {\n value: CLUSTERS_CAN_UPDATE_GENERATION,\n description: 'can update generation of a running cluster',\n initialRoles: [\n 'console:admin',\n 'accounts:clusterUpdates',\n 'console:C8ReleaseManager',\n ],\n },\n {\n value: CLUSTERS_CAN_UPDATE_GENERATION_YOLO,\n description:\n 'can update generation of a running cluster even if the generation is not reachable',\n initialRoles: ['console:god'],\n },\n {\n value: CLUSTERS_CAN_UPDATE_OPTIONAL_TELEMETRY,\n description:\n 'can enable or disable optional product telemetry for a cluster',\n // A customer asks their CSM or TAM to switch the category off, thus the\n // capability goes to `console:optionalTelemetryManager`. The population\n // that holds the role lives in the Camundi permission rules, not in the\n // name of the role. The console team keeps the permission, to help when\n // a change does not take effect.\n initialRoles: ['console:admin', 'console:optionalTelemetryManager'],\n },\n {\n value: CLUSTER_PLAN_CAN_MODIFY,\n description: 'can trigger modifications of a clusterplan',\n initialRoles: ['console:admin', 'console:clusterPlanManager'],\n },\n {\n value: RELEASE_TRAIN_PUBLISH,\n description: 'can publish new generations via the release train endpoint',\n initialRoles: ['console:admin', 'console:C8ReleaseManager'],\n },\n {\n value: APICLIENT_READ,\n description: 'can read API Clients Names of Organizations',\n initialRoles: ['accounts:read', 'accounts:orgCreator'],\n },\n {\n value: APICLIENT_DELETE,\n description: 'can read API Clients Names of Organizations',\n initialRoles: ['accounts:god'],\n },\n ]\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["ConsolePermissions"]
|
|
7
7
|
}
|
|
@@ -10,4 +10,4 @@ export declare enum ClusterPlanTypeCategory {
|
|
|
10
10
|
* @returns true if the category is ADVANCED_OFFERING or CUSTOM, false otherwise
|
|
11
11
|
*/
|
|
12
12
|
export declare function hasAvailabilityClass(category: ClusterPlanTypeCategory): boolean;
|
|
13
|
-
export declare function sortByClusterPlanTypeCategory(a: ClusterPlanTypeCategory | string, b: ClusterPlanTypeCategory | string): 1 |
|
|
13
|
+
export declare function sortByClusterPlanTypeCategory(a: ClusterPlanTypeCategory | string, b: ClusterPlanTypeCategory | string): 1 | -1 | 0;
|
|
@@ -94,3 +94,30 @@ export declare function validateClusterTtlUnlimited(input: {
|
|
|
94
94
|
reason?: unknown;
|
|
95
95
|
link?: unknown;
|
|
96
96
|
}): string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* ClusterTtlDeletionPayload is the payload of a `cluster-ttl-deletion`
|
|
99
|
+
* approval request. The action reads `clusterId` and `orgId`: console-backend
|
|
100
|
+
* tests the TTL again, and keeps a cluster that another org owns now. The
|
|
101
|
+
* name, the expiry and `ttlSetBy` are copies for a reader.
|
|
102
|
+
*/
|
|
103
|
+
export interface ClusterTtlDeletionPayload {
|
|
104
|
+
clusterId: string;
|
|
105
|
+
clusterName?: string;
|
|
106
|
+
/** The org that owned the cluster when the cron read it. The delete demands it. */
|
|
107
|
+
orgId: string;
|
|
108
|
+
/** The end of the TTL, as an ISO date. */
|
|
109
|
+
ttlExpiresAt: string;
|
|
110
|
+
/** The email of the person who set the expiry. See `ttlSetBy` of a cluster. */
|
|
111
|
+
ttlSetBy?: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* ClusterTtlDeletionResult is what console-backend answers when a
|
|
115
|
+
* `cluster-ttl-deletion` request runs. `kept` means that the cluster does not
|
|
116
|
+
* pass the TTL rules any more, and console-backend did not delete it. An
|
|
117
|
+
* extension, a move, the flag, or a failover sibling that is not healthy can
|
|
118
|
+
* each be the cause.
|
|
119
|
+
*/
|
|
120
|
+
export interface ClusterTtlDeletionResult {
|
|
121
|
+
clusterId: string;
|
|
122
|
+
outcome: 'deleted' | 'kept';
|
|
123
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/types/ClusterTtl.type.ts"],
|
|
4
|
-
"sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport { DAY, WEEK } from '../constants/duration.const.js'\n\n/**\n * CLUSTER_TTL_FEATURE_FLAG gates the TTL of a single cluster. It is not the\n * org-level `preprodClusterTtlHours` limit: both apply, and the earlier one\n * deletes the cluster.\n */\nexport const CLUSTER_TTL_FEATURE_FLAG = 'console.clusterTtl'\n\n/**\n * isClusterTtlStage tells if the cluster TTL can be on at the stage `stage`.\n * That is only dev and int. On prod, and on each other stage, the feature is\n * off for every reader, also when the flag is on.\n */\nexport const isClusterTtlStage = (stage: string | undefined): boolean =>\n stage === 'dev' || stage === 'int'\n\n/** CLUSTER_TTL_DURATIONS are the TTLs that end at a time. */\nexport const CLUSTER_TTL_DURATIONS = ['24h', '3d', '1w', '4w'] as const\n\nexport type ClusterTtlDuration = (typeof CLUSTER_TTL_DURATIONS)[number]\n\n/** CLUSTER_TTL_OPTIONS are the choices of the create form, in display order. */\nexport const CLUSTER_TTL_OPTIONS = [\n ...CLUSTER_TTL_DURATIONS,\n 'unlimited',\n] as const\n\nexport type ClusterTtlOption = (typeof CLUSTER_TTL_OPTIONS)[number]\n\n/** DEFAULT_CLUSTER_TTL_OPTION applies when an eligible create sends no `ttl`. */\nexport const DEFAULT_CLUSTER_TTL_OPTION: ClusterTtlOption = '24h'\n\nexport const CLUSTER_TTL_DURATION_MS: Readonly<\n Record<ClusterTtlDuration, number>\n> = {\n '24h': DAY,\n '3d': 3 * DAY,\n '1w': WEEK,\n '4w': 4 * WEEK,\n}\n\nexport const CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH = 500\nexport const CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH = 2048\n\n/**\n * CLUSTER_TTL_BACKFILL_REASON is the reason that the schema migration wrote\n * for each cluster that existed before the TTL. These rows are the only\n * unlimited TTLs with a reason and no link.\n */\nexport const CLUSTER_TTL_BACKFILL_REASON = 'Created before cluster TTL existed'\n\n/**\n * ClusterTtlDto is the TTL of one cluster. A response carries it only when\n * the reader may see the feature, thus an absent `ttl` means \"not shown\", not\n * \"unlimited\".\n */\nexport interface ClusterTtlDto {\n /** ISO-8601. Absent when the TTL is unlimited. */\n expiresAt?: string\n /**\n * Why the TTL is unlimited. Absent for a cluster that got no TTL, for\n * example one that a failover or a customer org created.\n */\n unlimitedReason?: string\n /** An http(s) URL, for example a GitHub issue. */\n unlimitedLink?: string\n}\n\n/** ClusterTtlUnlimited is the input that sets an unlimited TTL. */\nexport interface ClusterTtlUnlimited {\n reason: string\n link: string\n}\n\n/**\n * UpdateClusterTtlBody is the body of `PATCH api/admin/clusters/:clusterId/ttl`.\n * Give exactly one of the two fields.\n */\nexport type UpdateClusterTtlBody =\n | { extend: ClusterTtlDuration; unlimited?: never }\n | { unlimited: ClusterTtlUnlimited; extend?: never }\n\nexport const isClusterTtlDuration = (\n value: unknown,\n): value is ClusterTtlDuration =>\n (CLUSTER_TTL_DURATIONS as readonly unknown[]).includes(value)\n\nexport const isClusterTtlOption = (value: unknown): value is ClusterTtlOption =>\n (CLUSTER_TTL_OPTIONS as readonly unknown[]).includes(value)\n\n/** clusterTtlExpiresAt gives the expiry of a new TTL that starts at `now`. */\nexport function clusterTtlExpiresAt(\n duration: ClusterTtlDuration,\n now: Date = new Date(),\n): Date {\n return new Date(now.getTime() + CLUSTER_TTL_DURATION_MS[duration])\n}\n\n/**\n * extendClusterTtl gives the expiry after an extension. The extension starts\n * at the current expiry, or at `now` when that is in the past or when the TTL\n * is unlimited (`currentExpiresAt` undefined). Thus an extension never makes\n * the TTL shorter.\n */\nexport function extendClusterTtl({\n currentExpiresAt,\n duration,\n now = new Date(),\n}: {\n currentExpiresAt: Date | string | undefined\n duration: ClusterTtlDuration\n now?: Date\n}): Date {\n const currentMs =\n currentExpiresAt === undefined\n ? Number.NaN\n : new Date(currentExpiresAt).getTime()\n const startMs = Number.isNaN(currentMs)\n ? now.getTime()\n : Math.max(now.getTime(), currentMs)\n return new Date(startMs + CLUSTER_TTL_DURATION_MS[duration])\n}\n\n/**\n * isPastClusterTtl tells if the TTL of a cluster ran out. An unlimited TTL\n * (`expiresAt` undefined) or a value that is not a date never runs out.\n */\nexport function isPastClusterTtl({\n expiresAt,\n now = new Date(),\n}: {\n expiresAt: Date | string | undefined\n now?: Date\n}): boolean {\n if (expiresAt === undefined) return false\n const expiresMs = new Date(expiresAt).getTime()\n if (Number.isNaN(expiresMs)) return false\n return expiresMs < now.getTime()\n}\n\n/** isHttpUrl accepts an absolute `http:` or `https:` URL with a host. */\nexport function isHttpUrl(value: unknown): value is string {\n if (typeof value !== 'string' || /\\s/.test(value)) return false\n try {\n const url = new URL(value)\n return (\n (url.protocol === 'http:' || url.protocol === 'https:') &&\n url.hostname.length > 0\n )\n } catch {\n return false\n }\n}\n\n/**\n * validateClusterTtlUnlimited gives the first problem of an unlimited TTL\n * input as a message for the caller, or `undefined` when the input is valid.\n * The reason must hold text, and the link must be an http(s) URL. The length\n * limits apply to the trimmed values, because the server stores those.\n */\nexport function validateClusterTtlUnlimited(input: {\n reason?: unknown\n link?: unknown\n}): string | undefined {\n const reason =\n typeof input.reason === 'string' ? input.reason.trim() : undefined\n const link = typeof input.link === 'string' ? input.link.trim() : undefined\n if (!reason) {\n return 'An unlimited TTL needs a reason.'\n }\n if (reason.length > CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH) {\n return `The reason must not be longer than ${CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH} characters.`\n }\n if (!link) {\n return 'An unlimited TTL needs a link.'\n }\n if (link.length > CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH) {\n return `The link must not be longer than ${CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH} characters.`\n }\n if (!isHttpUrl(link)) {\n return 'The link must be an http or https URL.'\n }\n return undefined\n}\n"],
|
|
4
|
+
"sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport { DAY, WEEK } from '../constants/duration.const.js'\n\n/**\n * CLUSTER_TTL_FEATURE_FLAG gates the TTL of a single cluster. It is not the\n * org-level `preprodClusterTtlHours` limit: both apply, and the earlier one\n * deletes the cluster.\n */\nexport const CLUSTER_TTL_FEATURE_FLAG = 'console.clusterTtl'\n\n/**\n * isClusterTtlStage tells if the cluster TTL can be on at the stage `stage`.\n * That is only dev and int. On prod, and on each other stage, the feature is\n * off for every reader, also when the flag is on.\n */\nexport const isClusterTtlStage = (stage: string | undefined): boolean =>\n stage === 'dev' || stage === 'int'\n\n/** CLUSTER_TTL_DURATIONS are the TTLs that end at a time. */\nexport const CLUSTER_TTL_DURATIONS = ['24h', '3d', '1w', '4w'] as const\n\nexport type ClusterTtlDuration = (typeof CLUSTER_TTL_DURATIONS)[number]\n\n/** CLUSTER_TTL_OPTIONS are the choices of the create form, in display order. */\nexport const CLUSTER_TTL_OPTIONS = [\n ...CLUSTER_TTL_DURATIONS,\n 'unlimited',\n] as const\n\nexport type ClusterTtlOption = (typeof CLUSTER_TTL_OPTIONS)[number]\n\n/** DEFAULT_CLUSTER_TTL_OPTION applies when an eligible create sends no `ttl`. */\nexport const DEFAULT_CLUSTER_TTL_OPTION: ClusterTtlOption = '24h'\n\nexport const CLUSTER_TTL_DURATION_MS: Readonly<\n Record<ClusterTtlDuration, number>\n> = {\n '24h': DAY,\n '3d': 3 * DAY,\n '1w': WEEK,\n '4w': 4 * WEEK,\n}\n\nexport const CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH = 500\nexport const CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH = 2048\n\n/**\n * CLUSTER_TTL_BACKFILL_REASON is the reason that the schema migration wrote\n * for each cluster that existed before the TTL. These rows are the only\n * unlimited TTLs with a reason and no link.\n */\nexport const CLUSTER_TTL_BACKFILL_REASON = 'Created before cluster TTL existed'\n\n/**\n * ClusterTtlDto is the TTL of one cluster. A response carries it only when\n * the reader may see the feature, thus an absent `ttl` means \"not shown\", not\n * \"unlimited\".\n */\nexport interface ClusterTtlDto {\n /** ISO-8601. Absent when the TTL is unlimited. */\n expiresAt?: string\n /**\n * Why the TTL is unlimited. Absent for a cluster that got no TTL, for\n * example one that a failover or a customer org created.\n */\n unlimitedReason?: string\n /** An http(s) URL, for example a GitHub issue. */\n unlimitedLink?: string\n}\n\n/** ClusterTtlUnlimited is the input that sets an unlimited TTL. */\nexport interface ClusterTtlUnlimited {\n reason: string\n link: string\n}\n\n/**\n * UpdateClusterTtlBody is the body of `PATCH api/admin/clusters/:clusterId/ttl`.\n * Give exactly one of the two fields.\n */\nexport type UpdateClusterTtlBody =\n | { extend: ClusterTtlDuration; unlimited?: never }\n | { unlimited: ClusterTtlUnlimited; extend?: never }\n\nexport const isClusterTtlDuration = (\n value: unknown,\n): value is ClusterTtlDuration =>\n (CLUSTER_TTL_DURATIONS as readonly unknown[]).includes(value)\n\nexport const isClusterTtlOption = (value: unknown): value is ClusterTtlOption =>\n (CLUSTER_TTL_OPTIONS as readonly unknown[]).includes(value)\n\n/** clusterTtlExpiresAt gives the expiry of a new TTL that starts at `now`. */\nexport function clusterTtlExpiresAt(\n duration: ClusterTtlDuration,\n now: Date = new Date(),\n): Date {\n return new Date(now.getTime() + CLUSTER_TTL_DURATION_MS[duration])\n}\n\n/**\n * extendClusterTtl gives the expiry after an extension. The extension starts\n * at the current expiry, or at `now` when that is in the past or when the TTL\n * is unlimited (`currentExpiresAt` undefined). Thus an extension never makes\n * the TTL shorter.\n */\nexport function extendClusterTtl({\n currentExpiresAt,\n duration,\n now = new Date(),\n}: {\n currentExpiresAt: Date | string | undefined\n duration: ClusterTtlDuration\n now?: Date\n}): Date {\n const currentMs =\n currentExpiresAt === undefined\n ? Number.NaN\n : new Date(currentExpiresAt).getTime()\n const startMs = Number.isNaN(currentMs)\n ? now.getTime()\n : Math.max(now.getTime(), currentMs)\n return new Date(startMs + CLUSTER_TTL_DURATION_MS[duration])\n}\n\n/**\n * isPastClusterTtl tells if the TTL of a cluster ran out. An unlimited TTL\n * (`expiresAt` undefined) or a value that is not a date never runs out.\n */\nexport function isPastClusterTtl({\n expiresAt,\n now = new Date(),\n}: {\n expiresAt: Date | string | undefined\n now?: Date\n}): boolean {\n if (expiresAt === undefined) return false\n const expiresMs = new Date(expiresAt).getTime()\n if (Number.isNaN(expiresMs)) return false\n return expiresMs < now.getTime()\n}\n\n/** isHttpUrl accepts an absolute `http:` or `https:` URL with a host. */\nexport function isHttpUrl(value: unknown): value is string {\n if (typeof value !== 'string' || /\\s/.test(value)) return false\n try {\n const url = new URL(value)\n return (\n (url.protocol === 'http:' || url.protocol === 'https:') &&\n url.hostname.length > 0\n )\n } catch {\n return false\n }\n}\n\n/**\n * validateClusterTtlUnlimited gives the first problem of an unlimited TTL\n * input as a message for the caller, or `undefined` when the input is valid.\n * The reason must hold text, and the link must be an http(s) URL. The length\n * limits apply to the trimmed values, because the server stores those.\n */\nexport function validateClusterTtlUnlimited(input: {\n reason?: unknown\n link?: unknown\n}): string | undefined {\n const reason =\n typeof input.reason === 'string' ? input.reason.trim() : undefined\n const link = typeof input.link === 'string' ? input.link.trim() : undefined\n if (!reason) {\n return 'An unlimited TTL needs a reason.'\n }\n if (reason.length > CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH) {\n return `The reason must not be longer than ${CLUSTER_TTL_UNLIMITED_REASON_MAX_LENGTH} characters.`\n }\n if (!link) {\n return 'An unlimited TTL needs a link.'\n }\n if (link.length > CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH) {\n return `The link must not be longer than ${CLUSTER_TTL_UNLIMITED_LINK_MAX_LENGTH} characters.`\n }\n if (!isHttpUrl(link)) {\n return 'The link must be an http or https URL.'\n }\n return undefined\n}\n\n/**\n * ClusterTtlDeletionPayload is the payload of a `cluster-ttl-deletion`\n * approval request. The action reads `clusterId` and `orgId`: console-backend\n * tests the TTL again, and keeps a cluster that another org owns now. The\n * name, the expiry and `ttlSetBy` are copies for a reader.\n */\nexport interface ClusterTtlDeletionPayload {\n clusterId: string\n clusterName?: string\n /** The org that owned the cluster when the cron read it. The delete demands it. */\n orgId: string\n /** The end of the TTL, as an ISO date. */\n ttlExpiresAt: string\n /** The email of the person who set the expiry. See `ttlSetBy` of a cluster. */\n ttlSetBy?: string\n}\n\n/**\n * ClusterTtlDeletionResult is what console-backend answers when a\n * `cluster-ttl-deletion` request runs. `kept` means that the cluster does not\n * pass the TTL rules any more, and console-backend did not delete it. An\n * extension, a move, the flag, or a failover sibling that is not healthy can\n * each be the cause.\n */\nexport interface ClusterTtlDeletionResult {\n clusterId: string\n outcome: 'deleted' | 'kept'\n}\n"],
|
|
5
5
|
"mappings": "AAMA,SAAS,KAAK,YAAY;AAOnB,MAAM,2BAA2B;AAOjC,MAAM,oBAAoB,CAAC,UAChC,UAAU,SAAS,UAAU;AAGxB,MAAM,wBAAwB,CAAC,OAAO,MAAM,MAAM,IAAI;AAKtD,MAAM,sBAAsB;AAAA,EACjC,GAAG;AAAA,EACH;AACF;AAKO,MAAM,6BAA+C;AAErD,MAAM,0BAET;AAAA,EACF,OAAO;AAAA,EACP,MAAM,IAAI;AAAA,EACV,MAAM;AAAA,EACN,MAAM,IAAI;AACZ;AAEO,MAAM,0CAA0C;AAChD,MAAM,wCAAwC;AAO9C,MAAM,8BAA8B;AAiCpC,MAAM,uBAAuB,CAClC,UAEC,sBAA6C,SAAS,KAAK;AAEvD,MAAM,qBAAqB,CAAC,UAChC,oBAA2C,SAAS,KAAK;AAGrD,SAAS,oBACd,UACA,MAAY,oBAAI,KAAK,GACf;AACN,SAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,wBAAwB,QAAQ,CAAC;AACnE;AAQO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,MAAM,oBAAI,KAAK;AACjB,GAIS;AACP,QAAM,YACJ,qBAAqB,SACjB,OAAO,MACP,IAAI,KAAK,gBAAgB,EAAE,QAAQ;AACzC,QAAM,UAAU,OAAO,MAAM,SAAS,IAClC,IAAI,QAAQ,IACZ,KAAK,IAAI,IAAI,QAAQ,GAAG,SAAS;AACrC,SAAO,IAAI,KAAK,UAAU,wBAAwB,QAAQ,CAAC;AAC7D;AAMO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,MAAM,oBAAI,KAAK;AACjB,GAGY;AACV,MAAI,cAAc,OAAW,QAAO;AACpC,QAAM,YAAY,IAAI,KAAK,SAAS,EAAE,QAAQ;AAC9C,MAAI,OAAO,MAAM,SAAS,EAAG,QAAO;AACpC,SAAO,YAAY,IAAI,QAAQ;AACjC;AAGO,SAAS,UAAU,OAAiC;AACzD,MAAI,OAAO,UAAU,YAAY,KAAK,KAAK,KAAK,EAAG,QAAO;AAC1D,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,YACG,IAAI,aAAa,WAAW,IAAI,aAAa,aAC9C,IAAI,SAAS,SAAS;AAAA,EAE1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,4BAA4B,OAGrB;AACrB,QAAM,SACJ,OAAO,MAAM,WAAW,WAAW,MAAM,OAAO,KAAK,IAAI;AAC3D,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,yCAAyC;AAC3D,WAAO,sCAAsC,uCAAuC;AAAA,EACtF;AACA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,MAAI,KAAK,SAAS,uCAAuC;AACvD,WAAO,oCAAoC,qCAAqC;AAAA,EAClF;AACA,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AACA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -28,6 +28,28 @@ export interface ClusterUsageMetricsData {
|
|
|
28
28
|
generalUsers?: number;
|
|
29
29
|
deployedModels?: number;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* One row of the usage metadata of an organization: the unique task users
|
|
33
|
+
* and the deployed models that console counted for one billing period
|
|
34
|
+
* (`GET api/orgs/:orgId/clusters/usage/value-metrics-metadata`).
|
|
35
|
+
*
|
|
36
|
+
* `startTimestamp` is the start of the contract period that the row belongs
|
|
37
|
+
* to. A row is the whole period, so the list of an organization holds one
|
|
38
|
+
* row for each period that console counted.
|
|
39
|
+
*/
|
|
40
|
+
export interface ClusterUsageMetadataDto {
|
|
41
|
+
id: number;
|
|
42
|
+
orgId: string;
|
|
43
|
+
startTimestamp: string | Date;
|
|
44
|
+
taskUsers: {
|
|
45
|
+
clusterId: string;
|
|
46
|
+
identifier: string;
|
|
47
|
+
}[];
|
|
48
|
+
deployedModels: {
|
|
49
|
+
clusterId: string;
|
|
50
|
+
count: number;
|
|
51
|
+
}[];
|
|
52
|
+
}
|
|
31
53
|
export interface ClusterUsageDataRequest {
|
|
32
54
|
orgStartDateMap: Map<string, {
|
|
33
55
|
startDate: Date;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JVM_OPTION_PATTERN is the syntax of one flag that the CRD accepts. It is not
|
|
3
|
+
* the full check: parseJvmOption also refuses a flag that the Camunda launcher
|
|
4
|
+
* sets, for example `-XX:+ExitOnOutOfMemoryError`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const JVM_OPTION_PATTERN: RegExp;
|
|
7
|
+
/** JVM_OPTION_MAX_LENGTH is the `items:MaxLength` of `jvm.options` in the CRD. */
|
|
8
|
+
export declare const JVM_OPTION_MAX_LENGTH = 256;
|
|
9
|
+
/** JVM_OPTIONS_MAX_ITEMS is the `MaxItems` of `jvm.options` in the CRD. */
|
|
10
|
+
export declare const JVM_OPTIONS_MAX_ITEMS = 64;
|
|
11
|
+
/** JVM_OPTIONS_MODIFICATION_KEYS are the cluster modification keys that hold a list of JVM flags. */
|
|
12
|
+
export declare const JVM_OPTIONS_MODIFICATION_KEYS: readonly ["zeebe.broker.jvm.options", "gateway.jvm.options"];
|
|
13
|
+
/** JvmOptionsModificationKey is one of JVM_OPTIONS_MODIFICATION_KEYS. */
|
|
14
|
+
export type JvmOptionsModificationKey = (typeof JVM_OPTIONS_MODIFICATION_KEYS)[number];
|
|
15
|
+
/** JVM_OPTIONS_TARGETS names the ZeebeCluster spec component whose `jvm.options` each key sets. */
|
|
16
|
+
export declare const JVM_OPTIONS_TARGETS: {
|
|
17
|
+
readonly 'zeebe.broker.jvm.options': "zeebeBroker";
|
|
18
|
+
readonly 'gateway.jvm.options': "gateway";
|
|
19
|
+
};
|
|
20
|
+
/** ParsedJvmOption is a valid flag with the key that names its setting. */
|
|
21
|
+
export type ParsedJvmOption = {
|
|
22
|
+
key: string;
|
|
23
|
+
arg: string;
|
|
24
|
+
};
|
|
25
|
+
/** isJvmOptionsModificationKey tells if `key` is in JVM_OPTIONS_MODIFICATION_KEYS. */
|
|
26
|
+
export declare function isJvmOptionsModificationKey(key: string): key is JvmOptionsModificationKey;
|
|
27
|
+
/**
|
|
28
|
+
* isUnderJvmSpec tells if `key` names a `jvm` object of the spec, or a path in
|
|
29
|
+
* it, for example `zeebe.broker.jvm.options.0`. Only the keys of
|
|
30
|
+
* JVM_OPTIONS_MODIFICATION_KEYS may set it: the plan overlay turns any other
|
|
31
|
+
* such key into a list or an object in the spec.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isUnderJvmSpec(key: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* requiresEnvVarsOverride tells if only a caller with `canOverrideEnvVars` can
|
|
36
|
+
* set the modification key `key`: an `envVars` key, the JVM options keys, and
|
|
37
|
+
* every key under them, because the plan overlay turns a key such as
|
|
38
|
+
* `zeebe.broker.envVars.0` into the same field. The operator merges the JVM
|
|
39
|
+
* options into `JAVA_TOOL_OPTIONS`, and replaces matching flags in
|
|
40
|
+
* `JAVA_OPTS`, so they act like the env vars.
|
|
41
|
+
*/
|
|
42
|
+
export declare function requiresEnvVarsOverride(key: string): boolean;
|
|
43
|
+
type PlanModificationEntry = {
|
|
44
|
+
key: string;
|
|
45
|
+
value?: unknown;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* addsEnvVarsOverrideValue tells if `after` holds an entry with a key that
|
|
49
|
+
* needs `canOverrideEnvVars`, whose key and value are not in `allowed`. A
|
|
50
|
+
* caller without the permission can keep or remove such an entry, but cannot
|
|
51
|
+
* add one or change its value. A removal needs no check, because the
|
|
52
|
+
* activation of a config without the entry removes it too.
|
|
53
|
+
*/
|
|
54
|
+
export declare function addsEnvVarsOverrideValue(allowed: ReadonlyArray<PlanModificationEntry> | undefined, after: ReadonlyArray<PlanModificationEntry> | undefined): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* parseJvmOption returns the key and the flag, or an error message when `arg`
|
|
57
|
+
* is too long, does not match JVM_OPTION_PATTERN, or names a flag that the
|
|
58
|
+
* Camunda launcher sets. Two flags with the same key set the same setting.
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseJvmOption(arg: string): ParsedJvmOption | {
|
|
61
|
+
error: string;
|
|
62
|
+
};
|
|
63
|
+
/** splitJvmOptions splits a stored value on any white space and drops empty tokens. */
|
|
64
|
+
export declare function splitJvmOptions(value: string | undefined): string[];
|
|
65
|
+
/** joinJvmOptions returns the stored form of a list: the flags joined by a space. */
|
|
66
|
+
export declare function joinJvmOptions(options: string[]): string;
|
|
67
|
+
/**
|
|
68
|
+
* validateJvmOptions returns one message per problem of `options`, or an empty
|
|
69
|
+
* array when `options` is valid. `existing` holds the flags that come before
|
|
70
|
+
* `options` in the list. They count for duplicates and for the maximum number
|
|
71
|
+
* of flags, but their own problems are not reported.
|
|
72
|
+
*/
|
|
73
|
+
export declare function validateJvmOptions(options: string[], existing?: string[]): string[];
|
|
74
|
+
/**
|
|
75
|
+
* validateJvmOptionsValue returns one message per problem of the stored value
|
|
76
|
+
* of a JVM options key, or an empty array when the value is valid. The stored
|
|
77
|
+
* value is a string of flags separated by white space.
|
|
78
|
+
*/
|
|
79
|
+
export declare function validateJvmOptionsValue(value: unknown): string[];
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const JVM_OPTION_PATTERN = /^(-XX:([+-][A-Za-z][A-Za-z0-9_]*|[A-Za-z][A-Za-z0-9_]*=[\x21\x23\x25\x26\x28-\x5b\x5d-\x7e]+)|-X(mx|ms|ss)[0-9]+[kKmMgGtT]?)$/;
|
|
2
|
+
const JVM_OPTION_MAX_LENGTH = 256;
|
|
3
|
+
const JVM_OPTIONS_MAX_ITEMS = 64;
|
|
4
|
+
const JVM_OPTIONS_MODIFICATION_KEYS = [
|
|
5
|
+
"zeebe.broker.jvm.options",
|
|
6
|
+
"gateway.jvm.options"
|
|
7
|
+
];
|
|
8
|
+
const JVM_OPTIONS_TARGETS = {
|
|
9
|
+
"zeebe.broker.jvm.options": "zeebeBroker",
|
|
10
|
+
"gateway.jvm.options": "gateway"
|
|
11
|
+
};
|
|
12
|
+
const SIZE_FLAG_KEYS = {
|
|
13
|
+
"-Xmx": "XX:MaxHeapSize",
|
|
14
|
+
"-Xms": "XX:InitialHeapSize",
|
|
15
|
+
"-Xss": "XX:ThreadStackSize"
|
|
16
|
+
};
|
|
17
|
+
const LAUNCHER_KEYS = ["XX:ExitOnOutOfMemoryError"];
|
|
18
|
+
function isJvmOptionsModificationKey(key) {
|
|
19
|
+
return JVM_OPTIONS_MODIFICATION_KEYS.includes(key);
|
|
20
|
+
}
|
|
21
|
+
const JVM_SPEC_PATHS = JVM_OPTIONS_MODIFICATION_KEYS.map(
|
|
22
|
+
(key) => key.slice(0, -".options".length)
|
|
23
|
+
);
|
|
24
|
+
function isUnderJvmSpec(key) {
|
|
25
|
+
return JVM_SPEC_PATHS.some(
|
|
26
|
+
(path) => key === path || key.startsWith(`${path}.`)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function requiresEnvVarsOverride(key) {
|
|
30
|
+
return key.split(".").includes("envVars") || isUnderJvmSpec(key);
|
|
31
|
+
}
|
|
32
|
+
function envVarsOverrideEntries(modifications) {
|
|
33
|
+
return (modifications ?? []).filter(({ key }) => requiresEnvVarsOverride(key)).map(({ key, value }) => JSON.stringify([key, String(value)]));
|
|
34
|
+
}
|
|
35
|
+
function addsEnvVarsOverrideValue(allowed, after) {
|
|
36
|
+
const known = new Set(envVarsOverrideEntries(allowed));
|
|
37
|
+
return envVarsOverrideEntries(after).some((entry) => !known.has(entry));
|
|
38
|
+
}
|
|
39
|
+
function keyOf(arg) {
|
|
40
|
+
if (arg.startsWith("-XX:")) {
|
|
41
|
+
const name = arg.slice("-XX:".length).replace(/^[+-]+/, "").split("=")[0];
|
|
42
|
+
return name === "" ? "" : `XX:${name}`;
|
|
43
|
+
}
|
|
44
|
+
return SIZE_FLAG_KEYS[arg.slice(0, 4)] ?? "";
|
|
45
|
+
}
|
|
46
|
+
function parseJvmOption(arg) {
|
|
47
|
+
if (arg.length > JVM_OPTION_MAX_LENGTH) {
|
|
48
|
+
return {
|
|
49
|
+
error: `"${arg}" is longer than ${JVM_OPTION_MAX_LENGTH} characters`
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (!JVM_OPTION_PATTERN.test(arg)) {
|
|
53
|
+
return {
|
|
54
|
+
error: `"${arg}" is not a JVM flag of the form -XX:+Name, -XX:-Name, -XX:Name=value or -Xmx, -Xms, -Xss with a size, where a value is printable ASCII without spaces, quotes, $ or backslashes`
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const key = keyOf(arg);
|
|
58
|
+
if (LAUNCHER_KEYS.includes(key)) {
|
|
59
|
+
return {
|
|
60
|
+
error: `"${arg}" cannot be changed, because the Camunda launcher sets it on the command line`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return { key, arg };
|
|
64
|
+
}
|
|
65
|
+
function splitJvmOptions(value) {
|
|
66
|
+
return value?.split(/\s+/).filter(Boolean) ?? [];
|
|
67
|
+
}
|
|
68
|
+
function joinJvmOptions(options) {
|
|
69
|
+
return options.join(" ");
|
|
70
|
+
}
|
|
71
|
+
function validateJvmOptions(options, existing = []) {
|
|
72
|
+
const errors = [];
|
|
73
|
+
const firstByKey = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const arg of existing) {
|
|
75
|
+
const parsed = parseJvmOption(arg);
|
|
76
|
+
if (!("error" in parsed) && !firstByKey.has(parsed.key)) {
|
|
77
|
+
firstByKey.set(parsed.key, arg);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (const arg of options) {
|
|
81
|
+
const parsed = parseJvmOption(arg);
|
|
82
|
+
if ("error" in parsed) {
|
|
83
|
+
errors.push(parsed.error);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const first = firstByKey.get(parsed.key);
|
|
87
|
+
if (first === void 0) {
|
|
88
|
+
firstByKey.set(parsed.key, arg);
|
|
89
|
+
} else {
|
|
90
|
+
errors.push(`"${arg}" sets the same flag as "${first}"`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (existing.length + options.length > JVM_OPTIONS_MAX_ITEMS) {
|
|
94
|
+
errors.push(`Use at most ${JVM_OPTIONS_MAX_ITEMS} JVM flags`);
|
|
95
|
+
}
|
|
96
|
+
return errors;
|
|
97
|
+
}
|
|
98
|
+
function validateJvmOptionsValue(value) {
|
|
99
|
+
if (typeof value !== "string") {
|
|
100
|
+
return ["JVM options must be a string of flags"];
|
|
101
|
+
}
|
|
102
|
+
return validateJvmOptions(splitJvmOptions(value));
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
JVM_OPTIONS_MAX_ITEMS,
|
|
106
|
+
JVM_OPTIONS_MODIFICATION_KEYS,
|
|
107
|
+
JVM_OPTIONS_TARGETS,
|
|
108
|
+
JVM_OPTION_MAX_LENGTH,
|
|
109
|
+
JVM_OPTION_PATTERN,
|
|
110
|
+
addsEnvVarsOverrideValue,
|
|
111
|
+
isJvmOptionsModificationKey,
|
|
112
|
+
isUnderJvmSpec,
|
|
113
|
+
joinJvmOptions,
|
|
114
|
+
parseJvmOption,
|
|
115
|
+
requiresEnvVarsOverride,
|
|
116
|
+
splitJvmOptions,
|
|
117
|
+
validateJvmOptions,
|
|
118
|
+
validateJvmOptionsValue
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=jvmOptions.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/jvmOptions.ts"],
|
|
4
|
+
"sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\n// Port of the parsing rules in pkg/jvm/options.go and of the limits in the\n// JVMSpec kubebuilder markers in api/cloud/v1alpha1/zeebecluster_types.go, both\n// in camunda/camunda-operator. The operator rejects flags that do not match, so\n// change both files together.\n\n/**\n * JVM_OPTION_PATTERN is the syntax of one flag that the CRD accepts. It is not\n * the full check: parseJvmOption also refuses a flag that the Camunda launcher\n * sets, for example `-XX:+ExitOnOutOfMemoryError`.\n */\nexport const JVM_OPTION_PATTERN =\n /^(-XX:([+-][A-Za-z][A-Za-z0-9_]*|[A-Za-z][A-Za-z0-9_]*=[\\x21\\x23\\x25\\x26\\x28-\\x5b\\x5d-\\x7e]+)|-X(mx|ms|ss)[0-9]+[kKmMgGtT]?)$/\n\n/** JVM_OPTION_MAX_LENGTH is the `items:MaxLength` of `jvm.options` in the CRD. */\nexport const JVM_OPTION_MAX_LENGTH = 256\n\n/** JVM_OPTIONS_MAX_ITEMS is the `MaxItems` of `jvm.options` in the CRD. */\nexport const JVM_OPTIONS_MAX_ITEMS = 64\n\n/** JVM_OPTIONS_MODIFICATION_KEYS are the cluster modification keys that hold a list of JVM flags. */\nexport const JVM_OPTIONS_MODIFICATION_KEYS = [\n 'zeebe.broker.jvm.options',\n 'gateway.jvm.options',\n] as const\n\n/** JvmOptionsModificationKey is one of JVM_OPTIONS_MODIFICATION_KEYS. */\nexport type JvmOptionsModificationKey =\n (typeof JVM_OPTIONS_MODIFICATION_KEYS)[number]\n\n/** JVM_OPTIONS_TARGETS names the ZeebeCluster spec component whose `jvm.options` each key sets. */\nexport const JVM_OPTIONS_TARGETS = {\n 'zeebe.broker.jvm.options': 'zeebeBroker',\n 'gateway.jvm.options': 'gateway',\n} as const satisfies Record<\n JvmOptionsModificationKey,\n 'zeebeBroker' | 'gateway'\n>\n\n// -Xmx, -Xms and -Xss set the same setting as their -XX spelling\nconst SIZE_FLAG_KEYS: Record<string, string> = {\n '-Xmx': 'XX:MaxHeapSize',\n '-Xms': 'XX:InitialHeapSize',\n '-Xss': 'XX:ThreadStackSize',\n}\n\n// the Camunda launcher passes these after JAVA_OPTS, so no option can change them\nconst LAUNCHER_KEYS = ['XX:ExitOnOutOfMemoryError']\n\n/** ParsedJvmOption is a valid flag with the key that names its setting. */\nexport type ParsedJvmOption = { key: string; arg: string }\n\n/** isJvmOptionsModificationKey tells if `key` is in JVM_OPTIONS_MODIFICATION_KEYS. */\nexport function isJvmOptionsModificationKey(\n key: string,\n): key is JvmOptionsModificationKey {\n return (JVM_OPTIONS_MODIFICATION_KEYS as readonly string[]).includes(key)\n}\n\n// The `jvm` objects of the spec that JVM_OPTIONS_MODIFICATION_KEYS set a list in.\nconst JVM_SPEC_PATHS = JVM_OPTIONS_MODIFICATION_KEYS.map((key) =>\n key.slice(0, -'.options'.length),\n)\n\n/**\n * isUnderJvmSpec tells if `key` names a `jvm` object of the spec, or a path in\n * it, for example `zeebe.broker.jvm.options.0`. Only the keys of\n * JVM_OPTIONS_MODIFICATION_KEYS may set it: the plan overlay turns any other\n * such key into a list or an object in the spec.\n */\nexport function isUnderJvmSpec(key: string): boolean {\n return JVM_SPEC_PATHS.some(\n (path) => key === path || key.startsWith(`${path}.`),\n )\n}\n\n/**\n * requiresEnvVarsOverride tells if only a caller with `canOverrideEnvVars` can\n * set the modification key `key`: an `envVars` key, the JVM options keys, and\n * every key under them, because the plan overlay turns a key such as\n * `zeebe.broker.envVars.0` into the same field. The operator merges the JVM\n * options into `JAVA_TOOL_OPTIONS`, and replaces matching flags in\n * `JAVA_OPTS`, so they act like the env vars.\n */\nexport function requiresEnvVarsOverride(key: string): boolean {\n return key.split('.').includes('envVars') || isUnderJvmSpec(key)\n}\n\ntype PlanModificationEntry = { key: string; value?: unknown }\n\n// One string for each entry with a key that requiresEnvVarsOverride names, so\n// that a Set compares the key and the value together.\nfunction envVarsOverrideEntries(\n modifications: ReadonlyArray<PlanModificationEntry> | undefined,\n): string[] {\n return (modifications ?? [])\n .filter(({ key }) => requiresEnvVarsOverride(key))\n .map(({ key, value }) => JSON.stringify([key, String(value)]))\n}\n\n/**\n * addsEnvVarsOverrideValue tells if `after` holds an entry with a key that\n * needs `canOverrideEnvVars`, whose key and value are not in `allowed`. A\n * caller without the permission can keep or remove such an entry, but cannot\n * add one or change its value. A removal needs no check, because the\n * activation of a config without the entry removes it too.\n */\nexport function addsEnvVarsOverrideValue(\n allowed: ReadonlyArray<PlanModificationEntry> | undefined,\n after: ReadonlyArray<PlanModificationEntry> | undefined,\n): boolean {\n const known = new Set(envVarsOverrideEntries(allowed))\n return envVarsOverrideEntries(after).some((entry) => !known.has(entry))\n}\n\nfunction keyOf(arg: string): string {\n if (arg.startsWith('-XX:')) {\n const name = arg\n .slice('-XX:'.length)\n .replace(/^[+-]+/, '')\n .split('=')[0]\n return name === '' ? '' : `XX:${name}`\n }\n return SIZE_FLAG_KEYS[arg.slice(0, 4)] ?? ''\n}\n\n/**\n * parseJvmOption returns the key and the flag, or an error message when `arg`\n * is too long, does not match JVM_OPTION_PATTERN, or names a flag that the\n * Camunda launcher sets. Two flags with the same key set the same setting.\n */\nexport function parseJvmOption(\n arg: string,\n): ParsedJvmOption | { error: string } {\n if (arg.length > JVM_OPTION_MAX_LENGTH) {\n return {\n error: `\"${arg}\" is longer than ${JVM_OPTION_MAX_LENGTH} characters`,\n }\n }\n\n if (!JVM_OPTION_PATTERN.test(arg)) {\n return {\n error: `\"${arg}\" is not a JVM flag of the form -XX:+Name, -XX:-Name, -XX:Name=value or -Xmx, -Xms, -Xss with a size, where a value is printable ASCII without spaces, quotes, $ or backslashes`,\n }\n }\n\n const key = keyOf(arg)\n if (LAUNCHER_KEYS.includes(key)) {\n return {\n error: `\"${arg}\" cannot be changed, because the Camunda launcher sets it on the command line`,\n }\n }\n\n return { key, arg }\n}\n\n/** splitJvmOptions splits a stored value on any white space and drops empty tokens. */\nexport function splitJvmOptions(value: string | undefined): string[] {\n return value?.split(/\\s+/).filter(Boolean) ?? []\n}\n\n/** joinJvmOptions returns the stored form of a list: the flags joined by a space. */\nexport function joinJvmOptions(options: string[]): string {\n return options.join(' ')\n}\n\n/**\n * validateJvmOptions returns one message per problem of `options`, or an empty\n * array when `options` is valid. `existing` holds the flags that come before\n * `options` in the list. They count for duplicates and for the maximum number\n * of flags, but their own problems are not reported.\n */\nexport function validateJvmOptions(\n options: string[],\n existing: string[] = [],\n): string[] {\n const errors: string[] = []\n const firstByKey = new Map<string, string>()\n\n for (const arg of existing) {\n const parsed = parseJvmOption(arg)\n if (!('error' in parsed) && !firstByKey.has(parsed.key)) {\n firstByKey.set(parsed.key, arg)\n }\n }\n\n for (const arg of options) {\n const parsed = parseJvmOption(arg)\n if ('error' in parsed) {\n errors.push(parsed.error)\n continue\n }\n\n const first = firstByKey.get(parsed.key)\n if (first === undefined) {\n firstByKey.set(parsed.key, arg)\n } else {\n errors.push(`\"${arg}\" sets the same flag as \"${first}\"`)\n }\n }\n\n if (existing.length + options.length > JVM_OPTIONS_MAX_ITEMS) {\n errors.push(`Use at most ${JVM_OPTIONS_MAX_ITEMS} JVM flags`)\n }\n\n return errors\n}\n\n/**\n * validateJvmOptionsValue returns one message per problem of the stored value\n * of a JVM options key, or an empty array when the value is valid. The stored\n * value is a string of flags separated by white space.\n */\nexport function validateJvmOptionsValue(value: unknown): string[] {\n if (typeof value !== 'string') {\n return ['JVM options must be a string of flags']\n }\n return validateJvmOptions(splitJvmOptions(value))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED