From e9eeca450f2cf2cab95751b0e032602184aa0936 Mon Sep 17 00:00:00 2001 From: Sourav-Kumar-19 Date: Thu, 21 May 2026 15:39:26 +0600 Subject: [PATCH 1/4] mssql missing ops Signed-off-by: Sourav-Kumar-19 --- .../ui/create-ui.yaml | 2 +- charts/kubedbcom-mssqlserver-editor/ui/functions.js | 12 +++++++++++- .../ui/functions.js | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml b/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml index 1408c9735c..02f966b1b3 100644 --- a/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml @@ -742,7 +742,7 @@ step: init: type: func value: checkHostnameOrIP - label: Expose via Gateway? + label: Expose via Gateway? schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch watcher: diff --git a/charts/kubedbcom-mssqlserver-editor/ui/functions.js b/charts/kubedbcom-mssqlserver-editor/ui/functions.js index 267ba31475..3d887d9947 100644 --- a/charts/kubedbcom-mssqlserver-editor/ui/functions.js +++ b/charts/kubedbcom-mssqlserver-editor/ui/functions.js @@ -1159,12 +1159,22 @@ export const useFunc = (model) => { const pathPrefix = `${domain}/db${routeRootPath}` const pathSplit = pathPrefix.split('/').slice(0, -1).join('/') const pathConstructedForKubedb = pathSplit + `/${reqType.toLowerCase()}?namespace=${namespace}` + const requestTypeMap = { + 'update-version': 'UpdateVersion', + 'scale-vertically': 'VerticalScaling', + 'scale-storage': 'VolumeExpansion', + 'horizontal-scale': 'HorizontalScaling', + restart: 'Restart', + reconfigure: 'Reconfigure', + 'tls-configure': 'ReconfigureTLS', + } + const requestType = requestTypeMap[reqType] || 'VerticalScaling' const isKube = !!storeGet('/route/params/actions') if (isKube) return pathConstructedForKubedb else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mssqlserveropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mssqlserveropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${requestType}` } function setValueFrom() { diff --git a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js index ee51bf58a3..9982d407a0 100644 --- a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js @@ -717,6 +717,7 @@ export const useFunc = (model) => { const opMap = { upgrade: 'UpdateVersion', updateVersion: 'UpdateVersion', + 'update-version': 'UpdateVersion', horizontalscaling: 'HorizontalScaling', verticalscaling: 'VerticalScaling', volumeexpansion: 'VolumeExpansion', From 24a4a7b222c06ac9040474100d38fab471cee40d Mon Sep 17 00:00:00 2001 From: Sourav-Kumar-19 Date: Mon, 25 May 2026 15:47:14 +0600 Subject: [PATCH 2/4] added cassandra ops Signed-off-by: Sourav-Kumar-19 --- .../ui/create-ui.yaml | 651 ++++++ .../ui/functions.js | 1937 +++++++++++++++++ package-lock.json | 6 + 3 files changed, 2594 insertions(+) create mode 100644 charts/opskubedbcom-cassandraopsrequest-editor/ui/create-ui.yaml create mode 100644 charts/opskubedbcom-cassandraopsrequest-editor/ui/functions.js create mode 100644 package-lock.json diff --git a/charts/opskubedbcom-cassandraopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-cassandraopsrequest-editor/ui/create-ui.yaml new file mode 100644 index 0000000000..df24d0ea8a --- /dev/null +++ b/charts/opskubedbcom-cassandraopsrequest-editor/ui/create-ui.yaml @@ -0,0 +1,651 @@ +step: +- elements: + - if: + name: showAndInitName + type: function + label: op_req_name + schema: schema/properties/metadata/properties/name + type: input + validation: + type: required + - disable: isNamespaceDisabled + hasGroup: isRancherManaged + if: + name: showAndInitNamespace + type: function + init: + type: func + value: initNamespace + label: Namespace + loader: getNamespaces + schema: schema/properties/metadata/properties/namespace + type: select + validation: + type: required + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - disable: isDatabaseRefDisabled + if: + name: showAndInitDatabaseRef + type: function + init: + type: func + value: initDatabaseRef + label: Database Ref + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + refresh: true + schema: schema/properties/spec/properties/databaseRef/properties/name + type: select + validation: + type: required + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + - if: + name: showConfigureOpsrequestLabel + type: function + label: config_ops_request + type: label-element + - disable: isDbDetailsLoading + if: + name: showAndInitOpsRequestType + type: function + init: + type: func + value: getRequestTypeFromRoute + isHorizontal: true + label: Type of Ops Request + options: + - description: Update your database to any version + text: Update Version + value: UpdateVersion + - description: Scale up or down pod count + text: Horizontal Scaling + value: HorizontalScaling + - description: Manage your CPU resources + text: Vertical Scaling + value: VerticalScaling + - description: Manage your database size + text: Volume Expansion + value: VolumeExpansion + - description: Restart your database + text: Restart + value: Restart + - description: Reconfigure your database + text: Reconfigure + value: Reconfigure + - description: Reconfigure your database tls configuration + text: Reconfigure TLS + value: ReconfigureTLS + schema: schema/properties/spec/properties/type + type: radio + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + - elements: + - init: + type: func + value: setValueFromDbDetails|/spec/version + label: Target Version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + subtitle: Select the desired MySQL version to which you want to update your + database. + type: select-compare + - if: + name: isVersionEmpty + type: function + label: "" + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + type: info + fixedBlock: true + if: + name: ifRequestTypeEqualsTo|UpdateVersion + type: function + label: Version + showLabels: true + type: block-layout + - elements: + - elements: + - header: Replica + init: + type: func + value: setValueFromDbDetails|/spec/replicas + label: Replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/member + subtitle: Define the total number of replicas for the database. Increasing + replicas improves fault tolerance and load distribution , while reducing + replicas conserves resources + type: input-compare + - hasIcon: true + label: Each replica represents an independent copy of your database. For example, + setting this to 3 creates three copies of the database for better availability. + type: info + if: + name: ifDbTypeEqualsTo|cluster|horizontalScaling + type: function + type: horizontal-layout + fixedBlock: true + if: + name: ifRequestTypeEqualsTo|HorizontalScaling + type: function + label: Horizontal Scaling Form + showLabels: true + type: block-layout + - elements: + - elements: + - init: + type: func + value: setMachine + label: Resources + loader: getMachines + schema: temp/properties/machine + subtitle: Compare your current machine configuration with the proposed memory + adjustments and make informed decisions for your database setup + type: machine-compare + validation: + name: isMachineValid + type: custom + watcher: + func: onMachineChange|mysql|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + - elements: + - elements: + - elements: + - label: Node Selection Policy + subtitle: Control where your workloads runs by configuring node selection + criteria. Use label selectors to match specific nodes or taints to + avoid unsuitable nodes + type: label-element + - label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/mysql/properties/nodeSelectionPolicy + type: select + hideBorder: true + showLabels: false + type: block-layout + - customClass: mt-20 + label: Label Selector: Specify key-value pairs to target nodes + that match your workload's requirements.
Taints: Define + tolerations for node taints to ensure your workload runs only on compatible + nodes + type: info + type: horizontal-layout + - label: Topology + subtitle: Define node topology preferences, such as zone or region. For + example, 'zone=us-central1-a' ensures workloads are deployed in that zone. + type: label-element + - elements: + - label: Key + schema: temp/topologyKey + type: input + validation: + name: isVerticalScaleTopologyRequired + type: custom + - label: Value + schema: temp/topologyValue + type: input + validation: + name: isVerticalScaleTopologyRequired + type: custom + type: horizontal-layout + label: Node Selection + showLabels: true + type: block-layout + - elements: + - elements: + - init: + type: func + value: setExporter|cpu + label: CPU + schema: schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setExporter|memory + label: Memory + schema: schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory + type: input + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory + showLabels: true + type: horizontal-layout + hideBlock: true + label: Exporter + showLabels: true + type: block-layout + label: MySQL vertical scaling + showLabels: false + type: block-layout + if: + name: ifRequestTypeEqualsTo|VerticalScaling + type: function + type: block-layout + - elements: + - elements: + - elements: + - label: Mode + subtitle: Not sure which mode to pick? Use Online Mode for smooth operations + with minimal disruption. Choose Offline Mode if you can afford a brief + downtime for added reliability during the volume expansion. + type: label-element + - label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + type: select + validation: + type: required + type: block-layout + type: horizontal-layout + - elements: + - elements: + - header: MySQL + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + label: Storage Size + schema: schema/properties/spec/properties/volumeExpansion/properties/mysql + subtitle: How much extra storage does your database need? Specify the size(e.g. + 2Gi for 2 gigabytes) so we can allocate it correctly + type: input-compare + validation: + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mysql + type: custom + type: horizontal-layout + fixedBlock: true + label: MySQL volume expansion + showLabels: true + type: block-layout + if: + name: ifRequestTypeEqualsTo|VolumeExpansion + type: function + label: Volume Expansion Form + type: block-layout + - elements: + - elements: + - label: "" + subtitle: Select a new configuration secret, apply a custom configuration, + or remove an existing setup to update your database settings + type: label-element + - elements: + - elements: + - customClass: mb-15 + label: Config Secret + subtitle: Select an existing secret or create a new one to apply to your + database configuration. + type: label-element + - customClass: mb-2 + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + refresh: fetchConfigSecrets + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + type: select + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - customClass: mt-15 + elements: + - label: "" + subtitle: Enter a unique name to identify this secret. + type: label-element + - label: Secret Name + schema: temp/properties/createSecret/properties/name + type: input + validation: + type: required + - buttonClass: is-light is-outlined + elements: + - label: Key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + schema: key + type: select + validation: + type: required + - height: 120px + label: Value + schema: value + type: textarea + keepInitial: true + label: String Data + schema: temp/properties/createSecret/properties/data + type: array-object-form + validation: + type: required + hasButton: + action: createNewConfigSecret + hasCancel: cancelCreateSecret + text: Save + if: + name: isCreateSecret + type: function + label: Create a New Config Secret + showLabels: true + type: block-layout + - editorHeight: 500px + hideFormatButton: true + if: + name: isNotCreateSecret + type: function + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + readonly: true + schema: temp/properties/newConfigSecret + type: multi-file-editor + validateContent: false + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + label: Config Secret + type: block-layout + - elements: + - customClass: mb-15 + label: New Apply Config + subtitle: Define custom configurations for your database using key-value + pairs. These parameters will overwrite existing settings.
Enter the + parameter you want to configure (e.g., max_connections). + type: label-element + - customClass: mb-2 + label: Configuration + loader: getConfigSecretsforAppyConfig + refresh: fetchConfigSecrets + schema: temp/properties/selectedConfiguration + type: select + - editorHeight: 500px + hideFormatButton: true + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + schema: temp/properties/applyConfig + type: multi-file-editor + validateContent: false + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + label: ApplyConfig + type: block-layout + - elements: + - customClass: mb-15 + label: Remove + subtitle: Selected a configuration secret from the available list to update + your database settings + type: label-element + - customClass: mb-2 + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + refresh: fetchConfigSecrets + schema: temp/properties/selectedConfigurationRemove + type: select + - editorHeight: 500px + hideFormatButton: true + init: + type: func + value: onRemoveConfigChange + readonly: true + schema: temp/properties/removeConfig + type: multi-file-editor + validateContent: false + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + label: Remove + type: block-layout + label: New Config Secret + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + schema: temp/properties/reconfigurationType + type: tab-layout + label: Configuration + type: block-layout + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + label: Reconfigure Form + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + type: block-layout + - elements: + - if: + name: hasTlsField + type: function + init: + type: func + value: initTlsOperation + label: TLS Operation + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + schema: temp/properties/tlsOperation + type: radio + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - fullwidth: true + if: + name: isTlsEnabled + type: function + label: Remove TLS + schema: schema/properties/spec/properties/tls/properties/remove + type: switch + - fullwidth: true + if: + name: isTlsEnabled + type: function + label: Rotate Certificates + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + type: switch + - elements: + - fullwidth: true + init: + type: func + value: setValueFromDbDetails|/spec/tls/requireSSL + label: Require SSL + schema: schema/properties/spec/properties/tls/properties/requireSSL + type: switch + if: + name: showIssuerRefAndCertificates + type: function + label: Require SSL + type: block-layout + - elements: + - disable: true + init: + type: func + value: initIssuerRefApiGroup + label: API Group + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + type: input + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + type: select + validation: + name: isIssuerRefRequired + type: custom + - init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + type: select + validation: + name: isIssuerRefRequired + type: custom + if: + name: showIssuerRefAndCertificates + type: function + label: Issuer Reference + showLabels: true + type: block-layout + - elements: + - buttonClass: is-light is-outlined + elements: + - disable: disableAlias + label: Alias + loader: fetchAliasOptions + schema: alias + type: select + validation: + type: required + - label: Secret Name + schema: secretName + type: input + - label: Duration + schema: duration + type: input + - label: Renew Before + schema: renewBefore + type: input + - buttonClass: is-light is-outlined + element: + label: Organization + type: input + label: Organizations + schema: subject/properties/organizations + type: array-item-form + - buttonClass: is-light is-outlined + element: + label: Country + type: input + label: Countries + schema: subject/properties/countries + type: array-item-form + - buttonClass: is-light is-outlined + element: + label: Organizational Unit + type: input + label: Organizational Units + schema: subject/properties/organizationalUnits + type: array-item-form + - buttonClass: is-light is-outlined + element: + label: Province + type: input + label: Provinces + schema: subject/properties/provinces + type: array-item-form + - buttonClass: is-light is-outlined + element: + label: DNS Name + type: input + label: DNS Names + schema: dnsNames + type: array-item-form + - buttonClass: is-light is-outlined + element: + label: IP Address + type: input + label: IP Addresses + schema: ipAddresses + type: array-item-form + label: Certificates + schema: schema/properties/spec/properties/tls/properties/certificates + type: array-object-form + if: + name: showIssuerRefAndCertificates + type: function + label: Certificates + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + showLabels: false + type: block-layout + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + label: TLS + type: block-layout + - elements: + - label: Timeout + schema: schema/properties/spec/properties/timeout + subtitle: Specify the maximum time allowed for the operation to complete before + it times out + type: time-picker + - init: + type: func + value: setApplyToIfReady + label: Apply + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always + schema: schema/properties/spec/properties/apply + type: radio + label: OpsRequest Options + showLabels: true + type: block-layout + loader: getDbDetails + type: single-step-form +type: multi-step-form diff --git a/charts/opskubedbcom-cassandraopsrequest-editor/ui/functions.js b/charts/opskubedbcom-cassandraopsrequest-editor/ui/functions.js new file mode 100644 index 0000000000..52a2a8edf5 --- /dev/null +++ b/charts/opskubedbcom-cassandraopsrequest-editor/ui/functions.js @@ -0,0 +1,1937 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} +const machines = { + 'db.t.micro': { + resources: { + requests: { + cpu: '250m', + memory: '512Mi', + }, + limits: { + cpu: '500m', + memory: '1Gi', + }, + }, + }, + 'db.t.small': { + resources: { + requests: { + cpu: '1', + memory: '1Gi', + }, + limits: { + cpu: '2', + memory: '2Gi', + }, + }, + }, + 'db.t.medium': { + resources: { + requests: { + cpu: '1', + memory: '2Gi', + }, + limits: { + cpu: '2', + memory: '4Gi', + }, + }, + }, + 'db.t.large': { + resources: { + requests: { + cpu: '1', + memory: '4Gi', + }, + limits: { + cpu: '2', + memory: '8Gi', + }, + }, + }, + 'db.t.xlarge': { + resources: { + requests: { + cpu: '2', + memory: '8Gi', + }, + limits: { + cpu: '4', + memory: '16Gi', + }, + }, + }, + 'db.t.2xlarge': { + resources: { + requests: { + cpu: '4', + memory: '16Gi', + }, + limits: { + cpu: '8', + memory: '32Gi', + }, + }, + }, + 'db.m.small': { + resources: { + requests: { + cpu: '500m', + memory: '912680550', + }, + limits: { + cpu: '1', + memory: '1825361100', + }, + }, + }, + 'db.m.large': { + resources: { + requests: { + cpu: '1', + memory: '4Gi', + }, + limits: { + cpu: '2', + memory: '8Gi', + }, + }, + }, + 'db.m.xlarge': { + resources: { + requests: { + cpu: '2', + memory: '8Gi', + }, + limits: { + cpu: '4', + memory: '16Gi', + }, + }, + }, + 'db.m.2xlarge': { + resources: { + requests: { + cpu: '4', + memory: '16Gi', + }, + limits: { + cpu: '8', + memory: '32Gi', + }, + }, + }, + 'db.m.4xlarge': { + resources: { + requests: { + cpu: '8', + memory: '32Gi', + }, + limits: { + cpu: '16', + memory: '64Gi', + }, + }, + }, + 'db.m.8xlarge': { + resources: { + requests: { + cpu: '16', + memory: '64Gi', + }, + limits: { + cpu: '32', + memory: '128Gi', + }, + }, + }, + 'db.m.12xlarge': { + resources: { + requests: { + cpu: '24', + memory: '96Gi', + }, + limits: { + cpu: '48', + memory: '192Gi', + }, + }, + }, + 'db.m.16xlarge': { + resources: { + requests: { + cpu: '32', + memory: '128Gi', + }, + limits: { + cpu: '64', + memory: '256Gi', + }, + }, + }, + 'db.m.24xlarge': { + resources: { + requests: { + cpu: '48', + memory: '192Gi', + }, + limits: { + cpu: '96', + memory: '384Gi', + }, + }, + }, + 'db.r.large': { + resources: { + requests: { + cpu: '1', + memory: '8Gi', + }, + limits: { + cpu: '2', + memory: '16Gi', + }, + }, + }, + 'db.r.xlarge': { + resources: { + requests: { + cpu: '2', + memory: '16Gi', + }, + limits: { + cpu: '4', + memory: '32Gi', + }, + }, + }, + 'db.r.2xlarge': { + resources: { + requests: { + cpu: '4', + memory: '32Gi', + }, + limits: { + cpu: '8', + memory: '64Gi', + }, + }, + }, + 'db.r.4xlarge': { + resources: { + requests: { + cpu: '8', + memory: '96Gi', + }, + limits: { + cpu: '16', + memory: '192Gi', + }, + }, + }, + 'db.r.8xlarge': { + resources: { + requests: { + cpu: '16', + memory: '128Gi', + }, + limits: { + cpu: '32', + memory: '256Gi', + }, + }, + }, + 'db.r.12xlarge': { + resources: { + requests: { + cpu: '24', + memory: '192Gi', + }, + limits: { + cpu: '48', + memory: '384Gi', + }, + }, + }, + 'db.r.16xlarge': { + resources: { + requests: { + cpu: '32', + memory: '256Gi', + }, + limits: { + cpu: '64', + memory: '512Gi', + }, + }, + }, + 'db.r.24xlarge': { + resources: { + requests: { + cpu: '24', + memory: '384Gi', + }, + limits: { + cpu: '96', + memory: '768Gi', + }, + }, + }, +} + +const machineList = [ + 'custom', + 'db.t.micro', + 'db.t.small', + 'db.t.medium', + 'db.t.large', + 'db.t.xlarge', + 'db.t.2xlarge', + 'db.m.small', + 'db.m.large', + 'db.m.xlarge', + 'db.m.2xlarge', + 'db.m.4xlarge', + 'db.m.8xlarge', + 'db.m.12xlarge', + 'db.m.16xlarge', + 'db.m.24xlarge', + 'db.r.large', + 'db.r.xlarge', + 'db.r.2xlarge', + 'db.r.4xlarge', + 'db.r.8xlarge', + 'db.r.12xlarge', + 'db.r.16xlarge', + 'db.r.24xlarge', +] + +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.cnf'] + +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() + + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) + + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + + try { + ui = await axios.get( + `${packageviewUrlPrefix}/create-ui.yaml?name=${name}&sourceApiGroup=${sourceRef.apiGroup}&sourceKind=${sourceRef.kind}&sourceNamespace=${sourceRef.namespace}&sourceName=${sourceRef.name}&version=${version}&format=json`, + ) + language = await axios.get( + `${packageviewUrlPrefix}/language.yaml?name=${name}&sourceApiGroup=${sourceRef.apiGroup}&sourceKind=${sourceRef.kind}&sourceNamespace=${sourceRef.namespace}&sourceName=${sourceRef.name}&version=${version}&format=json`, + ) + const functionString = await axios.get( + `${packageviewUrlPrefix}/functions.js?name=${name}&sourceApiGroup=${sourceRef.apiGroup}&sourceKind=${sourceRef.kind}&sourceNamespace=${sourceRef.namespace}&sourceName=${sourceRef.name}&version=${version}`, + ) + // declare evaluate the functionString to get the functions Object + const evalFunc = new Function(functionString.data || '') + functions = evalFunc() + } catch (e) { + console.log(e) + } + + return { + ui: ui.data || {}, + language: language.data || {}, + functions, + } + } + + function returnFalse() { + return false + } + + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) + + const resources = (resp && resp.data && resp.data.items) || [] + + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') + + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mysqls`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') + const name = storeGet('/route/params/name') || getValue(model, '/spec/databaseRef/name') + + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mysqls/${name}` + const resp = await axios.get(url) + + setDiscriminatorValue('/dbDetails', resp.data || {}) + + return resp.data || {} + } else return {} + } + + let presetVersions = [] + setDiscriminatorValue('/filteredVersion', []) + async function getDbVersions() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + + let presets = storeGet('/kubedbuiPresets') || {} + if (!storeGet('/route/params/actions')) { + try { + const presetResp = await axios.get(url) + presets = presetResp.data?.spec?.values?.spec + } catch (e) { + console.log(e) + presets.status = String(e.status) + } + } + + try { + presetVersions = presets.admin?.databases?.MySQL?.versions?.available || [] + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null, updateConstraints: null }, + }, + }, + } + + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/mysqlversions`, + { + params: queryParams, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + const sortedVersions = resources.sort((a, b) => + versionCompare(a.spec.version, b.spec.version), + ) + + let ver = getValue(discriminator, '/dbDetails/spec/version') || '0' + const found = sortedVersions.find((item) => item.metadata.name === ver) + + if (found) ver = found.spec?.version + + const isGroupRepl = !!getValue(discriminator, '/dbDetails/spec/topology') + const allowed = isGroupRepl + ? found?.spec?.updateConstraints?.allowlist.groupReplication + : found?.spec?.updateConstraints?.allowlist.standalone + + const limit = allowed.length ? allowed[0] : '0.0' + + // keep only non deprecated & kubedb-ui-presets & within constraints of current version + // if presets.status is 404, it means no presets available, no need to filter with presets + const filteredMySQLVersions = sortedVersions.filter((item) => { + // default limit 0.0 means no restrictions, show all higher versions + if (limit === '0.0') + return ( + !item.spec?.deprecated && + (presets.status === '404' || + presetVersions.length === 0 || + presetVersions.includes(item.metadata?.name)) && + versionCompare(item.spec?.version, ver) >= 0 + ) + // if limit doesn't have any operator, it's a single version + else if (!limit.match(/^(>=|<=|>|<)/)) + return ( + !item.spec?.deprecated && + (presets.status === '404' || + presetVersions.length === 0 || + presetVersions.includes(item.metadata?.name)) && + item.spec?.version === limit + ) + // if limit has operator, check version with constraints + else + return ( + !item.spec?.deprecated && + (presets.status === '404' || + presetVersions.length === 0 || + presetVersions.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredMySQLVersions) + + return filteredMySQLVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + return { + text: `${name} (${specVersion})`, + value: name, + } + }) + } catch (e) { + console.log(e) + return [] + } + } + + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' + + let txt = 'No versions from this list can be selected as the target version: [ ' + + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' + }) + + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + return { + text: `${name} (${specVersion})`, + value: name, + } + }) + } + + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } + + function versionCompare(v1, v2) { + const arr1 = v1.split('.').map(Number) + const arr2 = v2.split('.').map(Number) + + for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { + const num1 = arr1[i] || 0 + const num2 = arr2[i] || 0 + + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal + } + + function isVersionWithinConstraints(version, constraints) { + let constraintsArr = [] + if (constraints.includes(',')) constraintsArr = constraints?.split(',')?.map((c) => c.trim()) + else constraintsArr = [constraints] + + for (let constraint of constraintsArr) { + let match = constraint.match(/^(>=|<=|>|<)/) + let operator = match ? match[0] : '' + let constraintVersion = constraint.replace(/^(>=|<=|>|<)/, '').trim() + + let comparison = versionCompare(version, constraintVersion) + if ( + (operator === '>=' && comparison < 0) || + (operator === '<=' && comparison > 0) || + (operator === '>' && comparison <= 0) || + (operator === '<' && comparison >= 0) + ) + return false + } + return true + } + + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') + + return selectedType === type + } + + function onRequestTypeChange() { + const selectedType = getValue(model, '/spec/type') + const reqTypeMapping = { + Upgrade: 'updateVersion', + UpdateVersion: 'updateVersion', + HorizontalScaling: 'horizontalScaling', + VerticalScaling: 'verticalScaling', + VolumeExpansion: 'volumeExpansion', + Restart: 'restart', + Reconfigure: 'configuration', + ReconfigureTLS: 'tls', + } + + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) + } + + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() + + if (dbType === 'standalone') return true + else return false + } else return false + } + + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + + const { spec } = dbDetails || {} + return spec?.tls || undefined + } + + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + + const { spec } = dbDetails || {} + const { topology } = spec || {} + const { mode } = topology || {} + + const verd = mode ? 'cluster' : 'standalone' + + return verd + } + + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } + + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } + + function asDatabaseOperation() { + return !!route.params.actions + } + + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') + + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) + + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } + + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() + + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + + if (ver) { + // For kubedb-ui + commit('wizard/model$update', { + path: '/metadata/name', + value: `${route.params.name}-${Math.floor(Date.now() / 1000)}-${lowerType}`, + force: true, + }) + } else { + // For cluster-ui + commit('wizard/model$update', { + path: '/metadata/name', + value: generateOpsRequestNameForClusterUI(getValue, model, route), + force: true, + }) + } + return !ver + } + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver + } + + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver + } + + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } + + function showAndInitOpsRequestType() { + const ver = asDatabaseOperation() + const opMap = { + upgrade: 'UpdateVersion', + updateVersion: 'UpdateVersion', + horizontalscaling: 'HorizontalScaling', + verticalscaling: 'VerticalScaling', + volumeexpansion: 'VolumeExpansion', + restart: 'Restart', + reconfiguretls: 'ReconfigureTLS', + reconfigure: 'Reconfigure', + } + if (ver) { + const operation = storeGet('/resource/activeActionItem/result/operationId') || '' + + const match = /^(.*)-opsrequest-(.*)$/.exec(operation) + if (match) { + const opstype = match[2] + commit('wizard/model$update', { + path: '/spec/type', + value: opMap[opstype], + force: true, + }) + } + } + + return !ver + } + + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() + + return value === verd + } + + // machine profile stuffs + // let machinesFromPreset = [] + + function getMachines() { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || {} + + const avlMachines = presets.admin?.machineProfiles?.available || [] + let arr = [] + if (avlMachines.length) { + arr = avlMachines.map((machine) => { + if (machine === 'custom') + return { text: machine, value: { machine, cpu: limits.cpu, memory: limits.memory } } + else { + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + const subtext = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + const text = machineData.name ? machineData.name : machineData.id + return { + text, + subtext, + value: { + machine: text, + cpu: machineData.limits.cpu, + memory: machineData.limits.memory, + }, + } + } else + return { text: machine, value: { machine, cpu: limits.cpu, memory: limits.memory } } + } + }) + } else { + arr = machineList + .map((machine) => { + if (machine === 'custom') + return { text: machine, value: { machine, cpu: limits.cpu, memory: limits.memory } } + const subtext = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { + text, + subtext, + value: { + machine: text, + cpu: machines[machine].resources.limits.cpu, + memory: machines[machine].resources.limits.memory, + }, + } + }) + .filter((val) => !!val) + } + return arr + } + + function setMachine() { + const dbDetails = getValue(discriminator, '/dbDetails') + const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || {} + const annotations = dbDetails?.metadata?.annotations || {} + const instance = annotations['kubernetes.io/instance-type'] + + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } + + const machine = parsedInstance || 'custom' + + const machinePresets = machinesFromPreset.find((item) => item.id === machine) + if (machinePresets) { + return { + machine: machine, + cpu: machinePresets.limits.cpu, + memory: machinePresets.limits.memory, + } + } else return { machine: 'custom', cpu: limits.cpu, memory: limits.memory } + } + + function onMachineChange(type, valPath) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, '/machine') + const machine = machinesFromPreset.find((item) => item.id === selectedMachine.machine) + + let obj = {} + if (selectedMachine.machine !== 'custom') { + if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } + else obj = machines[selectedMachine.machine]?.resources + } else { + const cpu = selectedMachine.cpu || '' + const memory = selectedMachine.memory || '' + obj = { + limits: { cpu: cpu, memory: memory }, + requests: { cpu: cpu, memory: memory }, + } + } + + const path = `/spec/verticalScaling/${type}/resources` + + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) + + // update metadata.annotations + const annotations = getValue(model, '/metadata/annotations') || {} + annotations['kubernetes.io/instance-type'] = selectedMachine.machine + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) + } + + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + let existingSecrets = [] + + async function fetchConfigSecrets() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') + + const name = getValue(model, '/spec/databaseRef/name') + const dbGroup = getValue(model, '/route/params/group') + const dbKind = getValue(store.state, '/resource/definition/result/kind') + const dbResource = getValue(model, '/route/params/resource') + const dbVersion = getValue(model, '/route/params/version') + + try { + const resp = await axios.post( + `/clusters/${owner}/${cluster}/proxy/ui.kubedb.com/v1alpha1/databaseinfos`, + { + apiVersion: 'ui.kubedb.com/v1alpha1', + kind: 'DatabaseInfo', + request: { + source: { + ref: { + name: name, + namespace: namespace, + }, + resource: { + group: dbGroup, + kind: dbKind, + name: dbResource, + version: dbVersion, + }, + }, + keys: ['kubedb-user.cnf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + + // Fetching all existing secrets + try { + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/secrets`) + resp.data?.items.forEach((item) => { + if (item.metadata?.name) { + existingSecrets.push(item.metadata.name) + } + }) + } catch (e) { + console.log(e) + } + } + + async function getConfigSecrets(type) { + type = type ? type + '/' : '' + const secretStatus = getValue(discriminator, `${type}createSecret/status`) + if (secretStatus === 'success') { + await fetchConfigSecrets() + } + const mappedSecrets = configSecrets.map((item) => { + return { text: item, value: item } + }) + mappedSecrets.push({ text: '+ Create a new Secret', value: 'Create' }) + return mappedSecrets + } + + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets + } + + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) + + if (!selectedConfiguration) { + return [] + } + + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) + + if (!configuration) { + return [] + } + + const result = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { + try { + // Decode base64 string + const decodedContent = atob(configuration.data[fileName]) + result.push({ + name: fileName, + content: decodedContent, + }) + } catch (e) { + console.error(`Error decoding ${fileName}:`, e) + result.push({ + name: fileName, + content: configuration.data[fileName], // Fallback to original if decode fails + }) + } + }) + + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result + } + + function getSelectedConfigurationName(configType, type) { + type = type ? type + '/' : '' + let path = '' + if (configType === 'create') path = `/spec/configuration/${type}/configSecret/name` + else if (configType === 'apply') path = `/${type}selectedConfiguration` + else if (configType === 'remove') path = `/${type}selectedConfigurationRemove` + + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) + + if (selectedConfiguration) + return { subtitle: ` You have selected ${selectedConfiguration} secret` } + else return { subtitle: 'No secret selected' } + } + + function getSelectedConfigurationValueForRemove(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfigurationRemove` + const selectedConfiguration = getValue(discriminator, path) + + if (!selectedConfiguration) { + return '' + } + + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) + + if (!configuration) { + return '' + } + + let data = {} + // Decode base64 and parse YAML for each key in the secret data + Object.keys(configuration.data).forEach((item) => { + try { + // Decode base64 string + const decodedString = atob(configuration.data[item]) + // Parse YAML string to object + const parsedYaml = yaml.load(decodedString) + // Store the parsed object with the filename as key + data[item] = parsedYaml + } catch (e) { + console.error(`Error parsing ${item}:`, e) + data[item] = atob(configuration.data[item]) // Fallback to decoded string + } + }) + + // Convert data object back to YAML string + return yaml.dump(data) + } + + async function createNewConfigSecret(type) { + type = type ? type + '/' : '' + const { user, cluster } = route.params + const url = `/clusters/${user}/${cluster}/resources` + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') + const secretName = getValue(discriminator, `${type}createSecret/name`) + const secretData = getValue(discriminator, `${type}createSecret/data`) + const secretDataObj = Object.fromEntries(secretData.map((item) => [item.key, item.value])) + + // Check uniqueness of secret name + if (existingSecrets.includes(secretName)) { + toast.error('A secret with this name already exists. Please choose another name.', { + timeout: 8000, + }) + return false + } + + try { + const res = await axios.post(url, { + apiVersion: 'v1', + stringData: secretDataObj, + kind: 'Secret', + metadata: { + name: secretName, + namespace: namespace, + }, + type: 'Opaque', + }) + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'success', + }) + commit('wizard/temp$update', { + path: `${type}createSecret/lastCreatedSecret`, + value: secretName, + }) + toast.success('Secret created successfully') + } catch (error) { + const errMsg = decodeError(error, 'Failed to create secret') + toast.error(errMsg, { timeout: 5000 }) + cancelCreateSecret() + } + return true + } + + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg + } + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) + } + + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' + + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } + + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } + + function onCreateSecretChange(type) { + type = type ? type + '/' : '' + const secretStatus = getValue(discriminator, `${type}createSecret/status`) + if (secretStatus === 'cancelled') return '' + else if (secretStatus === 'success') { + const name = getValue(discriminator, `${type}createSecret/lastCreatedSecret`) + + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } + + function cancelCreateSecret(type) { + type = type ? type + '/' : '' + commit('wizard/temp$delete', `${type}createSecret/name`) + commit('wizard/temp$delete', `${type}createSecret/data`) + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'cancelled', + }) + } + + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) + + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name && item.content) { + tempConfigObj[item.name] = item.content + } + }) + if (Object.keys(tempConfigObj).length === 0) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, + }) + } + + function setApplyConfig(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfiguration` + const selectedConfig = getValue(discriminator, configPath) + if (!selectedConfig) { + return [{ name: '', content: '' }] + } + const applyconfigData = secretConfigData.find((item) => { + if (item.componentName === selectedConfig) { + return item + } + }) + const { applyConfig } = applyconfigData + const configObj = [] + + if (applyConfig) { + Object.keys(applyConfig).forEach((fileName) => { + configObj.push({ + name: fileName, + content: applyConfig[fileName], + }) + }) + } + configSecretKeys.forEach((key) => { + if (!configObj.find((item) => item.name === key)) { + configObj.push({ name: key, content: '' }) + } + }) + return configObj + } + + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) + + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) + + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) + + if (!configuration.data) { + return [{ name: '', content: '' }] + } + + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { + try { + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) + } catch (e) { + console.error(`Error decoding ${fileName}:`, e) + configObj.push({ + name: fileName, + content: configuration.data[fileName], // Fallback to original if decode fails + }) + } + }) + return configObj + } + + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) + + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] + + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') + + try { + // Fetch the secret data from API + const secretResp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${selectedSecret}`, + ) + + const secretData = secretResp.data?.data || {} + const configObj = [] + + // Decode base64 and format as array of objects with name and content + Object.keys(secretData).forEach((fileName) => { + try { + // Decode base64 string + const decodedString = atob(secretData[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) + } catch (e) { + console.error(`Error decoding ${fileName}:`, e) + configObj.push({ + name: fileName, + content: secretData[fileName], // Fallback to original if decode fails + }) + } + }) + + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } + } + + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) + + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) + + const selfKey = getValue(discriminator, `createSecret/data/${index}/key`) + if (selfKey) { + remainingSecrets.push(selfKey) + } + const resSecret = remainingSecrets.map((item) => { + return { text: item, value: item } + }) + return resSecret + } + + let secretArray = [] + + function createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/console/${user}/kubernetes/${cluster}/core/v1/secrets/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/console/${user}/kubernetes/${cluster}/core/v1/secrets/create` + } + } + + function isConfigSelected() { + const secretName = getValue(model, '/spec/configuration/configSecret/name') + return !!secretName + } + + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } + + async function getNamespacedResourceList({ namespace, group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) + + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans + } + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) + + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans + } + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') + + let resources = await getNamespacedResourceList({ + namespace, + group, + version, + resource, + }) + + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } + + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) + + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } + + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') + + return reconfigurationType === value + } + + function onReconfigurationTypeChange() { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + setDiscriminatorValue('/applyConfig', []) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) + + commit('wizard/model$update', { + path: `/spec/configuration/removeCustomConfig`, + value: true, + force: true, + }) + } else { + commit('wizard/model$delete', `/spec/configuration/configSecret`) + commit('wizard/model$delete', `/spec/configuration/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + } + } + + // for tls + function hasTlsField() { + const tls = getDbTls() + + return !!tls + } + + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') + + if (kind) { + const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') + if (apiGroup) return apiGroup + return 'cert-manager.io' + } else return undefined + } + + async function getIssuerRefsName() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + // watchDependency('model#/spec/tls/issuerRef/kind') + // watchDependency('model#/metadata/namespace') + const kind = getValue(model, '/spec/tls/issuerRef/kind') + const namespace = getValue(model, '/metadata/namespace') + + if (kind === 'Issuer') { + const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/namespaces/${namespace}/issuers` + return getIssuer(url) + } else if (kind === 'ClusterIssuer') { + const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + + let presets = storeGet('/kubedbuiPresets') || {} + if (!storeGet('/route/params/actions')) { + try { + const presetResp = await axios.get(url) + presets = presetResp.data?.spec?.values?.spec + } catch (e) { + console.log(e) + presets.status = String(e.status) + } + } + let clusterIssuers = presets.admin?.clusterIssuers?.available || [] + if (presets.status === '404') { + const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` + return getIssuer(url) + } + return clusterIssuers + } else if (!kind) { + commit('wizard/model$delete', '/spec/tls/issuerRef/name') + return [] + } + + async function getIssuer(url) { + try { + const resp = await axios.get(url) + const resources = (resp && resp.data && resp.data.items) || [] + + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources + } catch (e) { + console.log(e) + return [] + } + } + } + + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + + commit('wizard/model$delete', '/spec/tls') + + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + commit('wizard/model$delete', '/spec/tls/certificates') + commit('wizard/model$delete', '/spec/tls/remove') + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + commit('wizard/model$delete', '/spec/tls/certificates') + commit('wizard/model$delete', '/spec/tls/rotateCertificates') + } + } + + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + + return verd + } + + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } + + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } + + // ************************************** Set db details ***************************************** + + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') + + return !dbDetails || !dbName + } + + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') + + const retValue = getValue(discriminator, `/dbDetails${path}`) + + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + + // direct model update required for reusable element. + // computed property is not applicable for reusable element + commit('wizard/model$update', { + path: commitPath, + value: retValue, + force: true, + }) + } + + return retValue || undefined + } + + function setConfigFiles() { + // watchDependency('model#/resources/secret_config/stringData') + const configFiles = getValue(model, '/resources/secret_config/stringData') + + const files = [] + + for (const item in configFiles) { + const obj = {} + obj.key = item + obj.value = configFiles[item] + files.push(obj) + } + + return files + } + + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } + + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } + + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } + + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } + + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } + + function setApplyToIfReady() { + return 'IfReady' + } + + function isVerticalScaleTopologyRequired() { + // watchDependency('discriminator#/topologyKey') + // watchDependency('discriminator#/topologyValue') + + const key = getValue(discriminator, '/topologyKey') + const value = getValue(discriminator, '/topologyValue') + const path = `/spec/verticalScaling/mysql/topology` + + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } + + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) + + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) + + if (inputSizeInBytes >= sizeInBytes) return + else return 'Cannot expand to lower volume!' + } catch (err) { + return err.message || 'Invalid' + } + } + + function parseSize(sizeStr) { + const units = { + '': 1, + K: 1e3, + M: 1e6, + G: 1e9, + T: 1e12, + P: 1e15, + E: 1e18, + Ki: 1024, + Mi: 1024 ** 2, + Gi: 1024 ** 3, + Ti: 1024 ** 4, + Pi: 1024 ** 5, + Ei: 1024 ** 6, + } + + const match = String(sizeStr).match(/^([0-9]+(?:\.[0-9]*)?)\s*([A-Za-z]*)$/) + if (!match) throw new Error('Invalid size format') + + const value = parseFloat(match[1]) + const unit = match[2] + + if (!(unit in units)) + throw new Error('Unrecognized unit. Available units are K, Ki, M, Mi, G, Gi etc') + + return value * units[unit] + } + + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } + + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] + + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } + + function disableAlias() { + return !!(model && model.alias) + } + + function getSelectedConfigSecret(type) { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return `You have selected ${selectedSecret} secret` || 'No secret selected' + } + + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) + + const spaces = ' '.repeat(indent) + + if (Array.isArray(obj)) { + return obj + .map((item) => `${spaces}- ${objectToYaml(item, indent + 1).trimStart()}`) + .join('\n') + } + + return Object.keys(obj) + .map((key) => { + const value = obj[key] + const keyLine = `${spaces}${key}:` + + if (value === null || value === undefined) { + return `${keyLine} null` + } + + if (typeof value === 'object') { + const nested = objectToYaml(value, indent + 1) + return `${keyLine}\n${nested}` + } + + if (typeof value === 'string') { + return `${keyLine} "${value}"` + } + + return `${keyLine} ${value}` + }) + .join('\n') + } + + function getSelectedConfigSecretValue(type) { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + let data + secretArray.forEach((item) => { + if (item.value === selectedSecret) { + data = objectToYaml(item.data).trim() || 'No Data Found' + } + }) + return data || 'No Data Found' + } + + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) + + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) + + if (reqVal) return reqVal + } + return limitVal + } + + function onExporterResourceChange(type) { + const commitPath = `/spec/verticalScaling/exporter/resources/requests/${type}` + const valPath = `/spec/verticalScaling/exporter/resources/limits/${type}` + const val = getValue(model, valPath) + if (val) + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, + }) + } + + function isMachineValid() { + const dbDetails = getValue(discriminator, '/dbDetails') + const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || {} + + const selectedMachine = getValue(discriminator, '/machine') + const selectedLimits = { cpu: selectedMachine.cpu, memory: selectedMachine.memory } + + if (JSON.stringify(limits) === JSON.stringify(selectedLimits)) { + return 'Resource limits are same as current machine configuration. Please select different resources or machine preset.' + } + return false + } + + return { + isMachineValid, + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isDatabaseRefDisabled, + isNamespaceDisabled, + onNamespaceChange, + onDbChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + setConfigFiles, + isConfigSelected, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..e662fec530 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "ui-wizards", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} From 55fc9acbaf67584fe9b053d34fdc57f0debb9b88 Mon Sep 17 00:00:00 2001 From: Sourav-Kumar-19 Date: Mon, 25 May 2026 16:38:13 +0600 Subject: [PATCH 3/4] added cassandra kubedbcom-ops Signed-off-by: Sourav-Kumar-19 --- .../ui/create-ui.yaml | 985 ++++++++++++++++++ .../ui/edit-ui.yaml | 724 +++++++++++++ .../ui/functions.js | 0 .../ui/language.yaml | 413 ++++++++ 4 files changed, 2122 insertions(+) create mode 100644 charts/kubedbcom-cassandra-editor/ui/create-ui.yaml create mode 100644 charts/kubedbcom-cassandra-editor/ui/edit-ui.yaml create mode 100644 charts/kubedbcom-cassandra-editor/ui/functions.js create mode 100644 charts/kubedbcom-cassandra-editor/ui/language.yaml diff --git a/charts/kubedbcom-cassandra-editor/ui/create-ui.yaml b/charts/kubedbcom-cassandra-editor/ui/create-ui.yaml new file mode 100644 index 0000000000..cbb925c8ef --- /dev/null +++ b/charts/kubedbcom-cassandra-editor/ui/create-ui.yaml @@ -0,0 +1,985 @@ +steps: +- form: + discriminator: + createAuthSecret: + type: boolean + password: + type: string + elements: + - disabled: isVariantAvailable + label: + text: labels.database.name + onChange: onNameChange + schema: + $ref: schema#/properties/metadata/properties/release/properties/name + type: input + - add_new_button: + label: labels.add_new_namespace + target: _blank + url: + function: getCreateNameSpaceUrl + disabled: isVariantAvailable + fetch: getResources|core|v1|namespaces + label: + text: labels.namespace + onChange: onNamespaceChange + refresh: true + schema: + $ref: schema#/properties/metadata/properties/release/properties/namespace + type: select + - disableUnselect: true + fetch: getMySqlVersions|catalog.kubedb.com|v1alpha1|mysqlversions + label: + text: labels.database.version + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/version + type: select + - individualItemDisabilityCheck: disableLableChecker + isArray: true + keys: + label: + text: labels.labels.key + label: + text: labels.labels.label + onChange: onLabelChange + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/metadata/properties/labels + type: key-value-input-form + values: + label: + text: labels.labels.value + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/metadata/properties/labels/additionalProperties + type: input + - isArray: true + keys: + label: + text: labels.annotations.key + label: + text: labels.annotations.label + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/metadata/properties/annotations + type: key-value-input-form + values: + label: + text: labels.annotations.value + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/metadata/properties/annotations/additionalProperties + type: input + - hasDescription: true + label: + text: labels.deletionPolicy + onChange: setStorageClass + options: + - description: options.deletionPolicy.delete.description + text: options.deletionPolicy.delete.label + value: Delete + - description: options.deletionPolicy.halt.description + text: options.deletionPolicy.halt.label + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: options.deletionPolicy.wipeOut.label + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: options.deletionPolicy.doNotTerminate.label + value: DoNotTerminate + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/deletionPolicy + type: radio + - label: + text: labels.database.secret + type: label-element + - computed: getCreateAuthSecret + onChange: onCreateAuthSecretChange + options: + - text: options.database.secret.existingSecret.label + value: false + - text: options.database.secret.customSecret.label + value: true + schema: + $ref: discriminator#/createAuthSecret + type: radio + - allowUserDefinedOption: true + fetch: getSecrets + if: showExistingSecretSection + label: + text: labels.secret + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/authSecret/properties/name + type: select + - computed: setAuthSecretPassword + hideValue: true + if: showPasswordSection + label: + text: Password + onChange: onAuthSecretPasswordChange + schema: + $ref: discriminator#/properties/password + type: input + - computed: setAddressType + label: + text: labels.use_address_type + options: + - text: DNS + value: DNS + - text: IP + value: IP + - text: IPv4 + value: IPv4 + - text: IPv6 + value: IPv6 + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/useAddressType + type: select + type: single-step-form + id: basic + title: steps.0.label +- form: + elements: + - alias: reusable_alert + chart: + name: uibytebuildersdev-component-alert + version: v0.30.0 + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/form/properties/alert + type: reusable-element + type: single-step-form + id: alert + title: labels.alert +- form: + discriminator: + activeDatabaseMode: + default: Standalone + type: string + elements: + - computed: setDatabaseMode + hasDescription: true + label: + text: labels.database.mode + onChange: deleteDatabaseModePath + options: + - description: options.database.mode.Standalone.description + text: options.database.mode.Standalone.label + value: Standalone + - description: options.database.mode.GroupReplication.description + text: options.database.mode.GroupReplication.label + value: GroupReplication + - description: options.database.mode.InnoDBCluster.description + text: options.database.mode.InnoDBCluster.label + value: InnoDBCluster + schema: + $ref: discriminator#/activeDatabaseMode + type: radio + - if: isNotEqualToDatabaseMode|Standalone + label: + text: labels.replicaset.number + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/replicas + type: input + - elements: + - fetch: getStorageClassNames + label: + text: labels.storage.class + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/storage/properties/storageClassName + type: select + - label: + text: labels.storage.size + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage + type: input + type: single-step-form + - elements: + - label: + text: labels.group_name + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/topology/properties/group/properties/name + type: input + - label: + text: labels.group_mode + options: + - text: options.groupMode.SinglePrimary + value: Single-Primary + - text: options.groupMode.MultiPrimary + value: Multi-Primary + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/topology/properties/group/properties/mode + type: radio + if: isEqualToDatabaseMode|GroupReplication + label: + text: labels.topology + show_label: true + type: single-step-form + type: single-step-form + id: topology + title: steps.1.label +- form: + discriminator: + configureTLS: + default: true + type: boolean + elements: + - computed: returnTrue + label: + text: labels.enable_tls + onChange: onTlsConfigureChange + schema: + $ref: discriminator#/configureTLS + type: switch + - elements: + - label: + text: labels.requireSSL_question + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/requireSSL + type: switch + - elements: + - computed: setApiGroup + disabled: true + label: + text: labels.api_group + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + type: input + - label: + text: labels.kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/tls/properties/issuerRef/properties/kind + type: select + - allowUserDefinedOption: true + fetch: getIssuerRefsName + label: + text: labels.name + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/tls/properties/issuerRef/properties/name + type: select + label: + text: labels.issuer_ref + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/tls/properties/issuerRef + type: single-step-form + - alias: reusable_certificates + chart: + name: uibytebuildersdev-component-certificates + version: v0.30.0 + functionCallbacks: + getAliasOptions: + $ref: functions#/getAliasOptions + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/tls/properties/certificates + type: reusable-element + if: showTlsConfigureSection + type: single-step-form + type: single-step-form + id: tls + title: steps.2.label +- form: + discriminator: + prePopulateDatabase: + type: string + elements: + - computed: returnStringYes + label: + text: labels.prePopulateDatabase + onChange: onPrePopulateDatabaseChange + options: + - text: options.yesOrNo.yes.text + value: "yes" + - text: options.yesOrNo.no.text + value: "no" + schema: + $ref: discriminator#/properties/prePopulateDatabase + type: radio + - discriminator: + dataSource: + type: string + elements: + - computed: initDataSource + label: + text: labels.dataSource + onChange: onDataSourceChange + options: + - text: options.dataSource.script.text + value: script + - text: options.dataSource.stashBackup.text + value: stashBackup + schema: + $ref: discriminator#/properties/dataSource + type: select + - discriminator: + sourceVolumeType: + type: string + elements: + - label: + text: labels.script.path + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/init/properties/script/properties/scriptPath + type: input + - label: + text: labels.script.volume + type: label-element + - computed: initVolumeType + label: + text: labels.script.volumeType + onChange: onVolumeTypeChange + options: + - text: options.scriptSourceVolumeType.configMap.text + value: configMap + - text: options.scriptSourceVolumeType.secret.text + value: secret + schema: + $ref: discriminator#/properties/sourceVolumeType + type: select + - allowUserDefinedOption: true + fetch: resourceNames|core|v1|configmaps + if: showConfigMapOrSecretName|configMap + label: + text: labels.script.volumeName + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/init/properties/script/properties/configMap/properties/name + type: select + - allowUserDefinedOption: true + fetch: resourceNames|core|v1|secrets + if: showConfigMapOrSecretName|secret + label: + text: labels.script.volumeName + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/init/properties/script/properties/secret/properties/secretName + type: select + if: showScriptOrStashForm|script + type: single-step-form + - elements: + - label: + text: labels.restoreSession.snapshot + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRestoreSession_init/properties/spec/properties/rules/properties/0/properties/snapshots/properties/0 + type: input + - discriminator: + repositoryChoise: + type: string + elements: + - label: + text: labels.repositories.title + type: label-element + - computed: setInitialRestoreSessionRepo + onChange: onInitRepositoryChoiseChange + options: + - text: options.createOrSelect.select.text + value: select + - text: options.createOrSelect.create.text + value: create + schema: + $ref: discriminator#/properties/repositoryChoise + type: radio + - allowUserDefinedOption: true + fetch: resourceNames|stash.appscode.com|v1alpha1|repositories + if: showRepositorySelectOrCreate|select + label: + text: labels.repositories.name + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRestoreSession_init/properties/spec/properties/repository/properties/name + type: select + - alias: repository_create_init + chart: + name: uibytebuildersdev-component-repository-create + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + if: showRepositorySelectOrCreate|create + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRepository_init_repo/properties/spec/properties/backend + type: reusable-element + type: single-step-form + - if: returnFalse + label: + text: labels.backupConfiguration.targetReference.name + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRestoreSession_init/properties/spec/properties/target/properties/ref/properties/name + type: input + - discriminator: + customizeRestoreJobRuntimeSettings: + type: string + elements: + - computed: initCustomizeRestoreJobRuntimeSettings + label: + isSubsection: true + text: labels.runtimeSettings.choise + onChange: onCustomizeRestoreJobRuntimeSettingsChange + options: + - text: options.yesOrNo.yes.text + value: "yes" + - text: options.yesOrNo.no.text + value: "no" + schema: + $ref: discriminator#/properties/customizeRestoreJobRuntimeSettings + type: radio + - alias: runtime_settings_init + chart: + name: uibytebuildersdev-component-runtime-settings + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + if: showRuntimeForm|yes + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRestoreSession_init/properties/spec/properties/runtimeSettings + type: reusable-element + type: single-step-form + if: showScriptOrStashForm|stashBackup + type: single-step-form + - if: returnFalse + label: + text: labels.waitForInitialRestore + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/init/properties/waitForInitialRestore + type: switch + if: showInitializationForm + type: single-step-form + type: single-step-form + id: initialization + title: steps.3.label +- form: + discriminator: + scheduleBackup: + type: string + elements: + - computed: returnStringYes + label: + text: labels.backup.title + onChange: onScheduleBackupChange + options: + - text: options.yesOrNo.yes.text + value: "yes" + - text: options.yesOrNo.no.text + value: "no" + schema: + $ref: discriminator#/properties/scheduleBackup + type: radio + - discriminator: + backupInvoker: + type: string + elements: + - computed: initBackupInvoker + label: + text: labels.backup.invoker + onChange: onBackupInvokerChange + options: + - text: Backup Configuration + value: backupConfiguration + - text: Backup Blueprint + value: backupBlueprint + schema: + $ref: discriminator#/properties/backupInvoker + type: select + - discriminator: + targetType: + type: string + elements: + - discriminator: + repositoryChoise: + type: string + elements: + - label: + isSubsection: true + text: labels.repositories.title + type: label-element + - computed: initRepositoryChoise + onChange: onRepositoryChoiseChange + options: + - text: options.createOrSelect.select.text + value: select + - text: options.createOrSelect.create.text + value: create + schema: + $ref: discriminator#/properties/repositoryChoise + type: radio + - allowUserDefinedOption: true + fetch: resourceNames|stash.appscode.com|v1alpha1|repositories + if: showRepositorySelectOrCreate|select + label: + text: labels.repositories.title + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/repository/properties/name + type: select + - alias: repository_create_backup + chart: + name: uibytebuildersdev-component-repository-create + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + if: showRepositorySelectOrCreate|create + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComRepository_repo/properties/spec/properties/backend + type: reusable-element + type: single-step-form + - if: returnFalse + label: + text: labels.backupConfiguration.targetReference.name + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/target/properties/ref/properties/name + type: input + - label: + text: labels.backupConfiguration.schedule + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/schedule + type: input + - label: + isSubsection: true + text: labels.backupConfiguration.retentionPolicy.title + type: label-element + - label: + text: labels.backupConfiguration.retentionPolicy.name + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/name + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepLast + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepLast + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepHourly + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepHourly + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepDaily + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepDaily + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepWeekly + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepWeekly + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepMonthly + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepMonthly + type: input + - label: + text: labels.backupConfiguration.retentionPolicy.keepYearly + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/keepYearly + type: input + - if: returnFalse + label: + text: labels.backupConfiguration.retentionPolicy.prune + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/retentionPolicy/properties/prune + type: switch + - discriminator: + customizeRestoreJobRuntimeSettings: + type: string + elements: + - computed: initCustomizeRestoreJobRuntimeSettingsForBackup + label: + isSubsection: true + text: labels.runtimeSettings.choiseForBackup + onChange: onCustomizeRestoreJobRuntimeSettingsChangeForBackup + options: + - text: options.yesOrNo.yes.text + value: "yes" + - text: options.yesOrNo.no.text + value: "no" + schema: + $ref: discriminator#/properties/customizeRestoreJobRuntimeSettings + type: radio + - alias: runtime_settings_backup + chart: + name: uibytebuildersdev-component-runtime-settings + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + if: showRuntimeForm|yes + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/stashAppscodeComBackupConfiguration/properties/spec/properties/runtimeSettings + type: reusable-element + type: single-step-form + if: showInvokerForm|backupConfiguration + label: + text: Backup Configuration form + type: single-step-form + - discriminator: + backupBlueprintName: + type: string + schedule: + type: string + taskParameters: + additionalProperties: + type: string + type: object + elements: + - label: + text: labels.backupBlueprint.title + type: label-element + - allowUserDefinedOption: true + computed: initFromAnnotationValue|stash.appscode.com/backup-blueprint + fetch: unNamespacedResourceNames|stash.appscode.com|v1beta1|backupblueprints + label: + text: labels.backupBlueprint.name + onChange: onBackupBlueprintNameChange + schema: + $ref: discriminator#/properties/backupBlueprintName + type: select + - computed: initFromAnnotationValue|stash.appscode.com/schedule + label: + text: labels.backupBlueprint.schedule + onChange: onBackupBlueprintScheduleChange + schema: + $ref: discriminator#/properties/schedule + type: input + - computed: initFromAnnotationKeyValue|params.stash.appscode.com/ + isArray: true + keys: + label: + text: Key + label: + text: labels.backupBlueprint.taskParameters + onChange: onTaskParametersChange + schema: + $ref: discriminator#/properties/taskParameters + type: key-value-input-form + values: + label: + text: Value + schema: + $ref: discriminator#/properties/taskParameters/additionalProperties + type: input + if: showInvokerForm|backupBlueprint + label: + text: Backup Blueprint form + type: single-step-form + if: showBackupForm + label: + text: Backup Form + type: single-step-form + type: single-step-form + id: backupconfiguration + title: steps.4.label +- form: + discriminator: + enableMonitoring: + default: true + type: boolean + elements: + - computed: returnTrue + label: + text: labels.enable_monitoring + onChange: onEnableMonitoringChange + schema: + $ref: discriminator#/enableMonitoring + type: switch + - discriminator: + customizeExporter: + default: true + type: boolean + elements: + - hasDescription: true + label: + text: labels.agent + onChange: onAgentChange + options: + - description: options.agent.prometheus_operator.description + text: options.agent.prometheus_operator.label + value: prometheus.io/operator + - description: options.agent.prometheus.description + text: options.agent.prometheus.label + value: prometheus.io + - description: options.agent.prometheus_builtin.description + text: options.agent.prometheus_builtin.label + value: prometheus.io/builtin + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/agent + type: radio + - elements: + - label: + text: labels.scrapping_interval + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMySQL/spec/monitor/agent + label: + text: labels.service_monitor_configuration + show_label: true + type: single-step-form + - elements: + - elements: + - addFormLabel: labels.endpoint + element: + elements: + - label: + text: labels.honor_labels + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints/items/properties/honorLabels + type: switch + - label: + text: labels.interval + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints/items/properties/interval + type: input + - label: + text: labels.path + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints/items/properties/path + type: input + - label: + text: labels.port + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints/items/properties/port + type: input + type: single-step-form + label: + text: labels.endpoints + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + tableContents: + - inTableColumn: true + label: + text: labels.honor_labels + path: honorLabels + type: value + typeOfValue: string + - inTableColumn: true + label: + text: labels.interval + path: interval + type: value + typeOfValue: string + - inTableColumn: true + label: + text: labels.path + path: path + type: value + typeOfValue: string + - inTableColumn: true + label: + text: labels.port + path: port + type: value + typeOfValue: string + type: single-step-form-array + - elements: + - fetch: getResources|core|v1|namespaces + label: + text: labels.matchNames + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + type: multiselect + if: returnFalse + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector + type: single-step-form + - elements: + - isArray: true + keys: + label: + text: labels.labels.key + label: + text: labels.labels.label + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + type: key-value-input-form + values: + label: + text: labels.labels.value + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels/additionalProperties + type: input + if: returnFalse + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + type: single-step-form + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec + type: single-step-form + if: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + label: + text: labels.service_monitor + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor + show_label: true + type: single-step-form + - if: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + individualItemDisabilityCheck: disableLableChecker + isArray: true + keys: + label: + text: labels.labels.key + label: + text: labels.labels.label + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + type: key-value-input-form + values: + label: + text: labels.labels.value + schema: + $ref: schema#/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels/additionalProperties + type: input + - label: + text: labels.exporter_configuration + type: label-element + - label: + text: labels.customize_exporter + onChange: onCustomizeExporterChange + schema: + $ref: discriminator#/customizeExporter + type: switch + - elements: + - label: + text: labels.resources + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + type: resource-input-form + - label: + text: labels.security_context + type: label-element + - label: + text: labels.run_as_user + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + type: input + - customClass: mb-0 + label: + text: labels.run_as_group + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + type: input + - label: + text: labels.port + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + type: input + - element: + label: + isSubsection: true + text: labels.args + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items + type: input + label: + text: labels.args + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + type: list-input-form + - alias: reusable_env + chart: + name: uibytebuildersdev-component-env + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/env + type: reusable-element + if: showCustomizeExporterSection + type: single-step-form + if: showMonitoringSection + type: single-step-form + type: single-step-form + id: monitoring + title: steps.5.label +- form: + elements: + - alias: pod_template_standalone + chart: + name: uibytebuildersdev-component-pod-template + version: v0.30.0 + dataContext: + namespace: + $ref: schema#/properties/metadata/properties/release/properties/namespace + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/podTemplate + type: reusable-element + type: single-step-form + id: pod-template + title: steps.6.label +- form: + elements: + - alias: reusable_service_templates + chart: + name: uibytebuildersdev-component-service-templates + version: v0.30.0 + moduleResolver: fetchJsons + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/serviceTemplates + type: reusable-element + type: single-step-form + id: networking + title: steps.7.label +- form: + elements: + - discriminator: + setCustomConfig: + type: string + elements: + - computed: returnStringYes + label: + text: labels.setCustomConfig + onChange: onSetCustomConfigChange + options: + - text: options.yesOrNo.yes.text + value: "yes" + - text: options.yesOrNo.no.text + value: "no" + schema: + $ref: discriminator#/properties/setCustomConfig + type: radio + - discriminator: + configuration: + type: string + configurationSource: + default: use-existing-config + type: string + elements: + - computed: setConfigurationSource + label: + text: labels.custom_config + onChange: onConfigurationSourceChange + options: + - text: options.configuration_source.use_existing_config.label + value: use-existing-config + - text: options.configuration_source.create_new_config.label + value: create-new-config + schema: + $ref: discriminator#/configurationSource + type: radio + - allowUserDefinedOption: true + fetch: getSecrets + if: isEqualToDiscriminatorPath|use-existing-config|/configurationSource + label: + text: labels.name + schema: + $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/configSecret/properties/name + type: select + - computed: setConfiguration + if: isEqualToDiscriminatorPath|create-new-config|/configurationSource + label: + text: labels.my_config_cnf + onChange: onConfigurationChange + schema: + $ref: discriminator#/properties/configuration + type: editor + if: isEqualToDiscriminatorPath|yes|/setCustomConfig + type: single-step-form + type: single-step-form + type: single-step-form + id: custom-config + title: steps.8.label +type: multi-step-form diff --git a/charts/kubedbcom-cassandra-editor/ui/edit-ui.yaml b/charts/kubedbcom-cassandra-editor/ui/edit-ui.yaml new file mode 100644 index 0000000000..1d58ee3546 --- /dev/null +++ b/charts/kubedbcom-cassandra-editor/ui/edit-ui.yaml @@ -0,0 +1,724 @@ +step: +- elements: + - if: + name: showScheduleBackup + type: function + init: + type: func + value: initScheduleBackupForEdit + isHorizontal: true + label: Schedule a Backup? + options: + - text: "Yes" + value: "yes" + - text: "No" + value: "no" + schema: temp/properties/scheduleBackup + type: radio + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - elements: + - if: + name: isBackupDataLoadedTrue + type: function + init: + type: func + value: setBackupType + isHorizontal: true + label: Select Backup Type + loader: getTypes + options: + - description: Create, Delete or Modify BackupConfig + text: BackupConfig + value: BackupConfig + - description: Enable/Disable BackupBlueprint + text: BackupBlueprint + value: BackupBlueprint + schema: temp/properties/backupType + type: radio + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - elements: + - label: Select Context + loader: getContext + schema: temp/properties/backupConfigContext + type: select + validation: + type: required + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - if: + name: showConfigList + type: function + label: Select BackupConfig + loader: getConfigList + schema: temp/properties/config + type: select + validation: + type: required + watcher: + func: onConfigChange + paths: + - temp/properties/config + - if: + name: showSchedule + type: function + label: Schedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + schema: temp/properties/schedule + type: input + validation: + type: required + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - fullwidth: true + if: + name: showPause + type: function + init: + type: func + value: setPausedValue + label: Paused + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + type: switch + watcher: + func: setPausedValue + paths: + - temp/properties/config + if: + name: isBackupType|BackupConfig + type: function + label: Config + type: block-layout + - elements: + - fullwidth: true + init: + type: func + value: setBlueprintSwitch + label: Enable Backup Blueprint + schema: temp/properties/blueprintEnabled + type: switch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + if: + name: isBackupType|BackupBlueprint + type: function + label: Blueprint + type: block-layout + - elements: + - fullwidth: true + init: + type: func + value: setArchiverSwitch + label: Enable Archiver + schema: temp/properties/archiverEnabled + type: switch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + if: + name: isBackupType|Archiver + type: function + label: Archiver + type: block-layout + if: + name: showBackupForm + type: function + label: Backup Form + loader: initBackupData + showLabels: false + type: block-layout + id: backupconfiguration + schema: schema/ + type: single-step-form +- elements: + - elements: + - label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/name + type: input + - if: + name: isRancherManaged + type: function + label: Select Namespace + loader: getNamespaces + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace + type: select + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace + - label: Select Db + loader: getMysqlDbs + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + type: select + validation: + type: required + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + if: + name: isConsole + type: function + type: block-layout + - if: + name: isConsole + type: function + label: Select Type + options: + - description: Scale your CPU Memory based on resource usage + text: Compute + value: compute + - description: Expand your database size based on volume usage + text: Storage + value: storage + schema: temp/properties/autoscalingType + type: radio + validation: + type: required + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + - elements: + - fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/compute/mysql/trigger + label: Trigger + schema: temp/properties/compute/properties/mysql/properties/trigger + type: switch + watcher: + func: onTriggerChange|compute/mysql + paths: + - temp/properties/compute/properties/mysql/properties/trigger + - label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for + scaling decisions, ensuring resource optimization and workload stability + type: label-element + - customClass: width-300 + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/podLifeTimeThreshold + type: input + - elements: + - customClass: width-300 + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/resourceDiffPercentage + type: threshold-input + - label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database + performance + type: label-element + - elements: + - header: Minimum Resource Limit + if: + name: hasAnnotations + type: function + init: + type: func + value: setAllowedMachine|mysql|min + label: Min Allowed Profile + loader: + name: getMachines|mysql|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + schema: temp/properties/allowedMachine-min + type: machine-compare + watcher: + func: onMachineChange|mysql + paths: + - temp/properties/allowedMachine-min + - elements: + - label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/minAllowed/properties/cpu + type: input-compare + - label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/minAllowed/properties/memory + type: input-compare + fixedBlock: true + if: + name: hasNoAnnotations + type: function + label: Min Allowed + showLabels: true + type: block-layout + - header: Maximum Resource Limit + if: + name: hasAnnotations + type: function + init: + type: func + value: setAllowedMachine|mysql|max + label: Max Allowed Profile + loader: + name: getMachines|mysql|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + schema: temp/properties/allowedMachine-max + type: machine-compare + watcher: + func: onMachineChange|mysql + paths: + - temp/properties/allowedMachine-max + - elements: + - label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/maxAllowed/properties/cpu + type: input-compare + - label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/maxAllowed/properties/memory + type: input-compare + fixedBlock: true + if: + name: hasNoAnnotations + type: function + label: Max Allowed + showLabels: true + type: block-layout + showLabels: false + type: block-layout + - label: Controlled Resources + loader: setControlledResources|mysql + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/controlledResources + type: select + - label: Container Controlled Values + options: + - text: Requests And Limits + value: RequestsAndLimits + - text: Requests Only + value: RequestsOnly + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/containerControlledValues + type: select + - elements: + - label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage/properties/scalingFactorPercentage + type: threshold-input + - label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage/properties/usageThresholdPercentage + type: threshold-input + if: + name: showStorageMemoryOption + type: function + label: In Memory Storage + showLabels: true + type: block-layout + label: Mysql + showLabels: true + type: block-layout + - elements: + - label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + type: select + - if: + name: isNodeTopologySelected + type: function + label: ScaleUp Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + type: threshold-input + - if: + name: isNodeTopologySelected + type: function + label: ScaleDown Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + type: threshold-input + if: + name: hasNoAnnotations + type: function + label: Node Topology + showLabels: true + type: block-layout + - elements: + - label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + type: time-picker + - init: + type: func + value: setApplyToIfReady + label: Apply + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + type: radio + if: + name: showOpsRequestOptions + type: function + label: Ops Request Options + showLabels: true + type: block-layout + loader: fetchTopologyMachines + showLabels: false + type: block-layout + id: compute-autoscaler + loader: getMysqlDbs + type: single-step-form +- elements: + - elements: + - fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/trigger + label: Trigger + schema: temp/properties/storage/properties/mysql/properties/trigger + type: switch + watcher: + func: onTriggerChange|storage/mysql + paths: + - temp/properties/storage/properties/mysql/properties/trigger + - label: Expansion Mode (Online/Offline) + subtitle: For Online Mode enables scaling without downtime by dynamically resizing + storage while the database remains operational and Offline Mode performs storage + scaling during scheduled downtime, ensuring consistency but requiring database + restarts. + type: label-element + - description: Select how the storage expansion should be handled. + label: Mode + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/expansionMode + type: select + - elements: + - label: UsageThreshold (%) + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/usageThreshold + subtitle: Set the threshold percentage of storage usage to trigger scaling. + type: threshold-input + - label: Scaling Rules + loader: setValueFromDbDetails|resources/kubedbComMySQL/spec/storage/resources/requests/storage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules + type: scaling-rules + watcher: + func: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules + - label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/upperBound + type: input + watcher: + func: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/upperBound + label: Mysql + showLabels: true + type: block-layout + - elements: + - label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + type: time-picker + - init: + type: func + value: setApplyToIfReady + label: Apply + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + type: radio + if: + name: showOpsRequestOptions + type: function + label: OpsRequest Options + showLabels: true + type: block-layout + showLabels: false + type: block-layout + id: storage-autoscaler + type: single-step-form +- elements: + - label: To update Exporter Resource section click on Create OpsRequest + type: label-element + - init: + type: func + value: getOpsRequestUrl|scale-vertically + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + type: anchor + - fullwidth: true + init: + type: func + value: isValueExistInModel|/resources/kubedbComMySQL/spec/monitor + label: Enable Monitoring + schema: temp/properties/enableMonitoring + type: switch + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - elements: + - init: + type: static + value: prometheus.io/operator + isHorizontal: true + label: Select a Monitoring Method + options: + - description: Inject metric exporter sidecar and creates a ServiceMonitor + text: Prometheus Operator + value: prometheus.io/operator + - description: Injects the metric exporter sidecar and let you customize ServiceMonitor + text: Custom ServiceMonitor + value: prometheus.io + - description: Inject metric exporter sidecar and add Prometheus annotations + to the stats Service + text: Custom Scrapper + value: prometheus.io/builtin + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/agent + type: radio + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/agent + - elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + if: + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMySQL/spec/monitor/agent + type: function + label: ServiceMonitor Configuration + showLabels: true + type: block-layout + - elements: + - buttonClass: is-light is-outlined + elements: + - fullwidth: true + label: Honor labels + schema: honorLabels + type: switch + - label: Interval + schema: interval + type: input + validation: + type: required + - label: Path + schema: path + type: input + validation: + type: required + - label: Port + schema: port + type: input + validation: + type: required + label: Endpoints + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + type: array-object-form + - if: + name: returnFalse + type: function + label: Match Namespaces + loader: getResources|core|v1|namespaces + multiple: true + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + type: select + - elements: + - label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + type: object-item + if: + name: returnFalse + type: function + showLabels: false + type: block-layout + if: + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + type: function + label: Service Monitor + showLabels: true + type: block-layout + - buttonClass: is-light is-outlined + if: + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + type: function + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + type: object-item + - label: Exporter Configuration + schema: "" + type: label-element + - fullwidth: true + init: + type: static + value: true + label: Customize Exporter Sidecar + schema: temp/properties/customizeExporter + type: switch + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - elements: + - if: + name: returnFalse + type: function + label: Resources + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + type: machine-compare + - label: Security Context + schema: "" + type: label-element + - label: Run as User + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + type: input + - label: Run as Group + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + type: input + - label: Port + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + type: input + - buttonClass: is-light is-outlined + element: + label: Args + type: input + init: + type: static + value: + - --compatible-mode + label: Args + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + type: array-item-form + - elements: + - buttonClass: is-light is-outlined + elements: + - label: Name + schema: name + type: input + validation: + type: required + - init: + type: func + value: setValueFrom + label: Value From + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + schema: temp/properties/valueFromType + type: radio + validation: + type: required + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - if: + name: isEqualToTemp|input + type: function + label: Value + schema: value + type: input + validation: + type: required + - if: + name: isEqualToTemp|configMap + type: function + label: ConfigMap Name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + schema: valueFrom/properties/configMapKeyRef/properties/name + type: select + validation: + type: required + - if: + name: isEqualToTemp|configMap + type: function + label: ConfigMap Key + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + schema: valueFrom/properties/configMapKeyRef/properties/key + type: select + - if: + name: isEqualToTemp|secret + type: function + label: Secret Name + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + schema: valueFrom/properties/secretKeyRef/properties/name + type: select + validation: + type: required + - if: + name: isEqualToTemp|secret + type: function + label: Secret Key + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + schema: valueFrom/properties/secretKeyRef/properties/key + type: select + init: + type: func + value: initEnvArray + label: Environment Variables + schema: temp/properties/env + type: array-object-form + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + label: Metadata + showLabels: false + type: block-layout + if: + name: showCustomizeExporterSection + type: function + label: Customer Exporter Section + showLabels: false + type: block-layout + if: + name: showMonitoringSection + type: function + type: block-layout + id: monitoring + loader: initMonitoring + type: single-step-form +- elements: + - fullwidth: true + init: + type: func + value: isBindingAlreadyOn + label: Expose Database + schema: temp/properties/binding + type: switch + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding + id: binding + type: single-step-form +type: multi-step-form diff --git a/charts/kubedbcom-cassandra-editor/ui/functions.js b/charts/kubedbcom-cassandra-editor/ui/functions.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/kubedbcom-cassandra-editor/ui/language.yaml b/charts/kubedbcom-cassandra-editor/ui/language.yaml new file mode 100644 index 0000000000..8a3600573e --- /dev/null +++ b/charts/kubedbcom-cassandra-editor/ui/language.yaml @@ -0,0 +1,413 @@ +en: + info: + metadata: + release: + name: Database Name + namespace: Namespace + spec: + annotations: Annotations + authSecret: + name: Name + password: Password + configOptions: Configuration Options + database: + mode: Database Mode + secret: Database Secret Type + labels: Labels + password: Password + replicaset: + name: Replica Set Name + number: Replica number + shards: + nodes: Shard Nodes + number: Shards Number + storage: + class: Storage Class Name + size: Storage Size + terminalPolicy: Terminal Policy + deletionPolicy: Deletion Policy + labels: + agent: Select a Monitoring Method + alert: Alert + alias: Alias + annotations: + key: Key + label: Annotations + value: Value + api_group: API Group + args: Args + backup: + invoker: Backup Invoker + title: Schedule a Backup? + backupBlueprint: + name: Blueprint Name + schedule: Schedule + taskParameters: Task Parameters + title: Backup Blueprint + backupConfiguration: + retentionPolicy: + keepDaily: Keep Daily + keepHourly: Keep Hourly + keepLast: Keep Last + keepMonthly: Keep Monthly + keepWeekly: Keep Weekly + keepYearly: Keep Yearly + name: Name + prune: Prune + title: Retention Policy + schedule: Schedule + targetReference: + apiVersion: Target ApiVersion + kind: Target Kind + name: Reference Name + title: Target Reference + type: Reference Type + taskName: Task Name + title: Backup Configuration + basic_info: Basic Information + certificate: Certificate + certificates: Certificates + client_auth_mode: Client Auth Mode + cluster_auth_mode: Cluster Authentication Mode + cluster_ip: Cluster IP + config_file: Configuration File + config_files: Configuration Files + configOptions: Configuration Options + configServer: Config Server + configServerNodes: Config Server Nodes + config_map_key: ConfigMap Key + config_map_name: ConfigMap Name + config_secret: ConfigSecret + configuration_files: Configuration + configuration_source: Configuration Source + controller_annotations: Controller Annotations + countries: Countries + country: Country + cpu: CPU + create_opsrequest: Create OpsRequest + custom_config: Select Custom Config Type + customize_config_server_pod_template: Customize Config Server Pod Template + customize_exporter: Customize Exporter Sidecar + customize_mongos_pod_template: Customize Mongos Pod Template + customize_shards_pod_template: Customize Shard Pod Template + dataSource: Data Source + database: + mode: Database Mode + name: Database Name + secret: Database Secret + version: Database Version + dns_name: DNS Name + dns_names: DNS Names + duration: Duration + effect: Effect + electionTick: Election Tick + enable_monitoring: Enable Monitoring + enable_tls: Enable TLS + endpoint: Endpoint + endpoints: Endpoints + environmentVariablesFrom: Environemt Variables From + environment_variable: Environment Variable + environment_variables: Environment Variables + exporter_configuration: Exporter Configuration + external_ip: External IP + external_ips: External IPs + external_traffic_policy: External Traffic Policy + filename: File Name + fs_group: Fs Group + group_mode: Group Mode + group_name: Group Name + health_check_node_port: Health Check Node Port + heartbeatTick: Heartbeat Tick + honor_labels: Honor labels + image_pull_secrets: Image Pull Secrets + initialization: Pre-populate your MySQL from backup/another database + interval: Interval + ip_address: IP Address + ip_addresses: IP Addresses + issuer_ref: Issuer Reference + key: Key + kind: Kind + labels: + key: Key + label: Labels + value: Value + leaderElection: Leader Election + level: Level + limit: Limit + load_balancer_ip: Load Balancer IP + load_balancer_source_range: Load Balancer Source Range + load_balancer_source_ranges: Load Balancer Source Ranges + matchNames: Match Namespaces + match_expression: Match Expression + match_expressions: Match Expressions + match_field: Match Field + match_fields: Match Fields + maximumLagBeforeFailover: Maximum Lag Before Failover + memory: Memory + user_conf: user.conf + mode: Mode + mongos: Mongos + mongosNodes: Mongos Nodes + my_config_cnf: my-config.cnf + name: Name + namespace: Namespace + new_secret_password: New Database Secret + node_port: Node Port + node_selector: Node Selector + node_selector_terms: Node Selector Terms + operator: Operator + organization: Organization + organizational_unit: Organizational Unit + organizational_units: Organizational Units + organizations: Organizations + password: Password (Keep it empty to autogenerate) + path: Path + period: Period + pod_annotations: Pod Annotations + pod_spec: Pod Spec + pod_template: Pod Template + pod_template_not_allowed: 'Specifying PodTemplate here is not allowed for sharded cluster. Please, use shard specific PodTemplate from the Topology section.' + port: Port + ports: Ports + prePopulateDatabase: Do you want to pre-populate your database? + preferred_during_scheduling_ignored_during_execution: Preferred During Scheduling Ignored During Execution + prometheus: Prometheus + province: Province + provinces: Provinces + renew_before: Renew Before + replicaset: + name: Replicaset Name + number: Replica Number + router_number: Router Replica Number + repositories: + backend: + bucket: Bucket + container: Container + endPoint: End Point + maxConnections: Maximum Connections + mountPath: Mount Path + path: Path + prefix: Prefix + pvcName: Claim Name + region: Region + secret: Storage Secret + server: Server + subPath: Sub Path + title: Backend + type: Type + url: URL + volumeSource: Select Volume Source + choise: '' + name: Name + title: Repository + request: Request + requireSSL_question: Require SSL? + resources: Resources + restoreSession: + name: Name + snapshot: Snapshot + title: Restore Session + role: Role + run_as_group: Run as Group + run_as_non_root: Run As Non Root? + run_as_user: Run as User + runtimeSettings: + choise: Customize Restore Job Runtime Settings? + choiseForBackup: Customize Backup Job Runtime Settings? + container: + ionice: + class: Class + classData: Class Data + title: Ionice + nice: + adjustment: Adjustment + title: Nice + resources: + cpu: CPU + limits: Limits + memory: Memory + requests: Requests + title: Resources + title: Container Runtime Settings + pod: + imagePullSecrets: Image Pull Secrets + serviceAccountName: Service Account Name + title: Pod Runtime Settings + securityContext: + fsGroup: FS Group + privileged: Privileged + runAsGroup: Run As Group + runAsNonRoot: Run As Non Root + runAsUser: Run As User + seLinuxOptions: + level: LeveL + role: Role + title: SE Linux Options + type: Type + user: User + title: Security Context + scrapping_interval: Scrapping Interval + script: + path: Script Path + volume: Source Volume + volumeName: Name + volumeType: Type + se_linux_options: SE Linux Options + secret: Secret + secret_key: Secret Key + secret_name: Secret Name + security_context: Security Context + service_account_name: Service Account Name + service_monitor: Service Monitor + service_monitor_configuration: ServiceMonitor Configuration + service_template: Service Template + service_template_annotations: Annotations + service_templates: Service Templates + setCustomConfig: Do you want to set custom config? + shard: Shard + shardNodes: Shard Nodes + shards: Shards + ssl_mode: SSL Mode + standbyMode: Standby Mode + storage: + class: Storage Class + size: Storage Size + subject: Subject + terminalPolicy: Terminal Policy + deletionPolicy: Deletion Policy + timeout_seconds: Timeout Seconds + toleration: Toleration + toleration_seconds: Toleration in seconds + tolerations: Tolerations + topology: Topology + to_update_config: To update this section click on Create OpsRequest + to_update_replicas: To update replicas click on Create OpsRequest + to_update_tls: To update this section click on Create OpsRequest + to_update_disabled_section: To update disabled section click on Create OpsRequest + to_update_exporter_resources: To update Exporter Resource section click on Create OpsRequest + type: Type + user: User + use_address_type: Use Address Type + value: Value + values: Values + waitForInitialRestore: Wait For Initial Restore? + weight: Weight + add_new_namespace: Add New Namespace + options: + agent: + prometheus: + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + label: Custom ServiceMonitor + prometheus_builtin: + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + label: Custom Scrapper + prometheus_operator: + description: Inject metric exporter sidecar and creates a ServiceMonitor + label: Prometheus Operator + configOptions: + backup: + description: Schedule periodic backup via Stash. + label: Backup + customConfig: + description: Configure MySQL with configuration files. + label: Custom Config + initialization: + description: Initialize database from backup or script. + label: Initialization + monitoring: + description: Setup Prometheus monitoring for the database. + label: Monitoring + networking: + description: Customize Services for the database. + label: Networking + podTemplate: + description: Customize runtime options for the database pods. + label: Pod Template + tls: + description: Secure database with TLS. + label: TLS + topology: + description: Configure your cluster topology. + label: Topology + configuration_source: + create_new_config: + label: Create New Config + same_as_config_server: + label: Same as ConfigServer + same_as_mongos: + label: Same as Mongos + same_as_shard: + label: Same as Shard + use_existing_config: + label: Use Existing Config + createOrSelect: + create: + text: Create New + select: + text: Use Existing + dataSource: + script: + text: Script + stashBackup: + text: Stash Backup + database: + mode: + GroupReplication: + description: GroupReplication for fault-tolerant replication topologies + label: GroupReplication + InnoDBCluster: + description: InnoDBCluster for high availability. + label: InnoDBCluster + Standalone: + description: Single node MySQL without high availability and sharding. + label: Standalone + secret: + customSecret: + label: Auto-generate auth secret + existingSecret: + label: Use existing auth secret + groupMode: + SinglePrimary: Single-Primary + MultiPrimary: Multi-Primary + scriptSourceVolumeType: + configMap: + text: ConfigMap + secret: + text: Secret + standbyMode: + hot: Hot + warm: Warm + storageClass: + standard: + label: Standard + deletionPolicy: + delete: + description: Keep only database Secrets and backed up data. + label: Delete + doNotTerminate: + description: Prevent deletion of the MySQL CRD. + label: DoNotTerminate + halt: + description: 'Keep PVCs, database Secrets and backed up data.' + label: Halt + wipeOut: + description: Delete everything including backed up data. + label: WipeOut + topologyMode: + GroupReplication: GroupReplication + InnoDBCluster: InnoDBCluster + yesOrNo: + 'no': + text: 'No' + 'yes': + text: 'Yes' + steps: + - label: Basic Information + - label: Configure Cluster + - label: TLS Configuration + - label: Initialization + - label: Backup + - label: Monitoring + - label: Pod Template + - label: Networking + - label: Custom Config \ No newline at end of file From ed99c694202e0b256ce4c3cd0817a530670a53c4 Mon Sep 17 00:00:00 2001 From: Sourav-Kumar-19 Date: Mon, 25 May 2026 16:54:38 +0600 Subject: [PATCH 4/4] added functions.js to cassandra Signed-off-by: Sourav-Kumar-19 --- .../ui/functions.js | 1486 +++++++++++++++++ 1 file changed, 1486 insertions(+) diff --git a/charts/kubedbcom-cassandra-editor/ui/functions.js b/charts/kubedbcom-cassandra-editor/ui/functions.js index e69de29bb2..ec977e6b73 100644 --- a/charts/kubedbcom-cassandra-editor/ui/functions.js +++ b/charts/kubedbcom-cassandra-editor/ui/functions.js @@ -0,0 +1,1486 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +// ************************* common functions ******************************************** +// eslint-disable-next-line no-empty-pattern +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + /********** Initialize Discriminator **************/ + + setDiscriminatorValue('repoInitialSelectionStatus', '') + setDiscriminatorValue('scheduleBackup', 'yes') + setDiscriminatorValue('backupType', '') + setDiscriminatorValue('isBackupDataLoaded', false) + setDiscriminatorValue('backupConfigContext', '') + setDiscriminatorValue('config', '') + setDiscriminatorValue('paused', false) + setDiscriminatorValue('schedule', '') + setDiscriminatorValue('blueprintEnabled', false) + setDiscriminatorValue('archiverEnabled', false) + + setDiscriminatorValue('binding', false) + setDiscriminatorValue('hidePreviewFromWizard', undefined) + + setDiscriminatorValue('/enableMonitoring', false) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') + setDiscriminatorValue('/env', []) + + // Autoscaler Discriminators + setDiscriminatorValue('/dbDetails', false) + setDiscriminatorValue('/topologyMachines', []) + setDiscriminatorValue('/allowedMachine-standalone-min', '') + setDiscriminatorValue('/allowedMachine-standalone-max', '') + setDiscriminatorValue('/allowedMachine-replicaSet-min', '') + setDiscriminatorValue('/allowedMachine-replicaSet-max', '') + setDiscriminatorValue('/allowedMachine-shard-min', '') + setDiscriminatorValue('/allowedMachine-shard-max', '') + setDiscriminatorValue('/allowedMachine-configServer-min', '') + setDiscriminatorValue('/allowedMachine-configServer-max', '') + setDiscriminatorValue('/allowedMachine-mongos-min', '') + setDiscriminatorValue('/allowedMachine-mongos-max', '') + let showStoragememory = false + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) + + initRepositoryChoiseForEdit() + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } + + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } + + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComMySQL annotation + deleteKubeDbComMySqlDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) + + // create stashAppscodeComBackupConfiguration and initialize it if not exists + + const dbName = getValue(model, '/metadata/release/name') + + if ( + !valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration') && + !isBluePrint + ) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration', + value: stashAppscodeComBackupConfiguration, + }) + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', + value: dbName, + force: true, + }) + } + } + } + + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false + } + + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) + const kubedbComMySQLAnnotations = + getValue(model, '/resources/kubedbComMySQL/metadata/annotations') || {} + + const isBluePrint = Object.keys(kubedbComMySQLAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) + + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + } + } + + function deleteKubeDbComMySqlDbAnnotation(getValue, model, commit) { + const annotations = getValue(model, '/resources/kubedbComMySQL/metadata/annotations') || {} + const filteredKeyList = + Object.keys(annotations).filter( + (k) => + k !== 'stash.appscode.com/backup-blueprint' && + k !== 'stash.appscode.com/schedule' && + !k.startsWith('params.stash.appscode.com/'), + ) || [] + const filteredAnnotations = {} + filteredKeyList.forEach((k) => { + filteredAnnotations[k] = annotations[k] + }) + commit('wizard/model$update', { + path: '/resources/kubedbComMySQL/metadata/annotations', + value: filteredAnnotations, + }) + } + + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } + + let initialModel = {} + let isBackupOn = false + let isBackupOnModel = false + let dbResource = {} + let initialDbMetadata = {} + let namespaceList = [] + let backupConfigurationsFromStore = {} + let valuesFromWizard = {} + let initialArchiver = {} + let isArchiverAvailable = false + let archiverObjectToCommit = {} + + async function initBackupData() { + // set initial model for further usage + initialModel = getValue(model, '/resources/coreKubestashComBackupConfiguration') + isBackupOnModel = !!initialModel + + // check db backup is enabled or not + backupConfigurationsFromStore = storeGet('/backup/backupConfigurations') + const configs = objectCopy(backupConfigurationsFromStore) + const { name, cluster, user, group, resource, spoke } = storeGet('/route/params') + const namespace = storeGet('/route/query/namespace') + const kind = storeGet('/resource/layout/result/resource/kind') + dbResource = getValue(model, '/resources/kubedbComMySQL') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined + + // get values.yaml to populate data when backup-config is being created + try { + const actionArray = storeGet('/resource/actions/result') + const editorDetails = actionArray[0]?.items[0]?.editor + const chartName = editorDetails?.name + const sourceApiGroup = editorDetails?.sourceRef?.apiGroup + const sourceKind = editorDetails?.sourceRef?.kind + const sourceNamespace = editorDetails?.sourceRef?.namespace + const sourceName = editorDetails?.sourceRef?.name + const chartVersion = editorDetails?.version + + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` + + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` + + const resp = await axios.get(url) + + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } + + // check storageclass archiver annotation + if (initialArchiver) { + isArchiverAvailable = true + } else { + const storageClassName = dbResource?.spec?.storage?.storageClassName + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses/${storageClassName}` + try { + const resp = await axios.get(url) + const archAnnotation = resp.data?.metadata?.annotations + const annotationKeyToFind = `${resource}.${group}/archiver` + if (archAnnotation[annotationKeyToFind]) { + isArchiverAvailable = true + archiverObjectToCommit = { + ref: { + name: archAnnotation[annotationKeyToFind], + namespace: 'kubedb', + }, + } + } + } catch (e) { + console.log(e) + } + } + + // check config with metadata name first + let config = configs?.find( + (item) => + item.metadata?.name === name && + item.spec?.target?.name === name && + item.spec?.target?.namespace === namespace && + item.spec?.target?.kind === kind && + item.spec?.target?.apiGroup === group, + ) + + // check config without metadata name if not found with metadata name + if (!config) + config = configs?.find( + (item) => + item.spec?.target?.name === name && + item.spec?.target?.namespace === namespace && + item.spec?.target?.kind === kind && + item.spec?.target?.apiGroup === group, + ) + + // set backup switch here + isBackupOn = !!config + + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset + + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends + + const tempSessions = valuesFromWizard.spec?.sessions + const tempRepositories = valuesFromWizard.spec?.sessions[0]?.repositories + tempRepositories[0]['encryptionSecret'] = encryptionSecret + tempRepositories[0].name = name + tempRepositories[0]['directory'] = `${namespace}/${name}` + + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } + + const apiGroup = storeGet('/route/params/group') + valuesFromWizard.spec['target'] = { name, namespace, apiGroup, kind } + const labels = dbResource.metadata?.labels + valuesFromWizard['metadata'] = { + name: `${name}-${Math.floor(Date.now() / 1000)}`, + namespace, + labels, + } + + setDiscriminatorValue('isBackupDataLoaded', true) + } + + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } + + function setBackupType() { + return 'BackupConfig' + } + + function getTypes() { + const arr = [ + { + description: 'Create, Delete or Modify BackupConfig', + text: 'BackupConfig', + value: 'BackupConfig', + }, + { + description: 'Enable/Disable BackupBlueprint', + text: 'BackupBlueprint', + value: 'BackupBlueprint', + }, + ] + + if ((dbResource?.spec?.replicaSet || dbResource?.spec?.shardTopology) && isArchiverAvailable) { + arr.push({ + description: 'Enable/Disable Archiver', + text: 'Archiver', + value: 'Archiver', + }) + } + return arr + } + + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') + commit('wizard/model$update', { + path: '/backupType', + value: type, + force: true, + }) + if (!isBackupOnModel) { + commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') + } else { + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: objectCopy(initialModel), + force: true, + }) + } + commit('wizard/model$delete', '/context') + commit('wizard/model$update', { + path: '/resources/kubedbComMySQL', + value: objectCopy(dbResource), + force: true, + }) + } + + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') + + return selectedType === type + } + + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations + + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } + + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } + + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } + + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComMySQL/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } + + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) + + if (type === 'annotations') { + const kind = storeGet('/resource/layout/result/resource/kind') + obj['blueprint.kubestash.com/name'] = 'kubedb' + obj['blueprint.kubestash.com/namespace'] = `${kind.toLowerCase()}-blueprint` + } else { + obj['kubedb.com/archiver'] = 'true' + } + + commit('wizard/model$update', { + path: `/resources/kubedbComMySQL/metadata/${type}`, + value: obj, + force: true, + }) + } + + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] + + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] + + commit('wizard/model$update', { + path: `/resources/kubedbComMySQL/metadata/${type}`, + value: obj, + force: true, + }) + } + + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } + + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') + commit('wizard/model$update', { + path: '/context', + value: context, + force: true, + }) + if (context === 'Create') { + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: valuesFromWizard, + force: true, + }) + } + if (context === 'Delete') setDiscriminatorValue('hidePreviewFromWizard', true) + else setDiscriminatorValue('hidePreviewFromWizard', undefined) + } + + function getConfigList() { + const configs = objectCopy(backupConfigurationsFromStore) + const { name, group } = storeGet('/route/params') + const namespace = storeGet('/route/query/namespace') + const kind = storeGet('/resource/layout/result/resource/kind') + const filteredList = configs?.filter( + (item) => + item.spec?.target?.name === name && + item.spec?.target?.namespace === namespace && + item.spec?.target?.kind === kind && + item.spec?.target?.apiGroup === group, + ) + const list = filteredList?.map((ele) => ele.metadata.name) + return list + } + + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) + + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, + force: true, + }) + } + + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } + + function setPausedValue() { + const backupConfig = storeGet('backup/backupConfigurations') || [] + const selectedConfigName = getValue(discriminator, '/config') + const namespace = storeGet('/route/query/namespace') + const selectedConfig = backupConfig.find( + (item) => item.metadata.name === selectedConfigName && item.metadata.namespace === namespace, + ) + return !!selectedConfig?.spec?.paused + } + + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } + + function showSchedule() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const configName = getValue(discriminator, '/config') + const contex = getValue(discriminator, '/backupConfigContext') + if (contex === 'Create') return true + else if (contex === 'Delete') return false + else return !!configName + } + + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } + + function getDefaultSchedule(modelPath) { + // watchDependency('discriminator#/config') + const config = getValue(discriminator, '/config') // only for computed behaviour + const session = getValue(model, modelPath) + return session?.length ? session[0]?.scheduler.schedule : '' + } + + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + + return repoInitialSelectionStatus + } + + function onInputChangeSchedule(modelPath, discriminatorName) { + const value = getValue(discriminator, `/${discriminatorName}`) + const session = getValue(model, modelPath) || [] + if (session.length) { + session[0].scheduler.schedule = value + commit('wizard/model$update', { + path: modelPath, + value: session, + }) + } + } + + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } + + /*********** Compute Autoscaling ************/ + + let autoscaleType = '' + let dbDetails = {} + let instance = '' + + function isKubedb() { + return !!storeGet('/route/params/actions') + } + + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name', + value: dbName, + force: true, + }) + const operation = storeGet('/route/params/actions') || '' + if (operation.length) { + const splitOp = operation.split('-') + if (splitOp.length > 2) autoscaleType = splitOp[2] + } + const date = Math.floor(Date.now() / 1000) + const modifiedName = `${dbName}-${date}-autoscaling-${autoscaleType}` + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } + } + + return !isKube + } + + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) + + const resources = (resp && resp.data && resp.data.items) || [] + + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], + force: true, + }) + } + } + + async function getMysqlDbs() { + // watchDependency('model#/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const storageEngine = getValue(model, '/resources/kubedbComMySQL/spec/storageEngine') + showStoragememory = storageEngine === 'inMemory' + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mysqls`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') || '' + const type = getValue(discriminator, '/autoscalingType') || '' + const date = Math.floor(Date.now() / 1000) + const resource = storeGet('/route/params/resource') + const scalingName = dbName ? dbName : resource + const modifiedName = `${scalingName}-${date}-autoscaling-${type ? type : ''}` + if (modifiedName) + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + + // delete the other type object from vuex wizard model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComMySQLAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute') + } + + async function fetchTopologyMachines() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations') || {} + instance = annotations['kubernetes.io/instance-type'] + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + if (instance) { + try { + const url = `/clusters/${user}/${cluster}/proxy/node.k8s.appscode.com/v1alpha1/nodetopologies/kubedb-ui-machine-profiles` + const resp = await axios.get(url) + + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } + } + + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' + } + + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComMySQLAutoscaler/spec/${type}/trigger` + + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } + + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] + + return !!instance + } + + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx + + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) + + // Return object with machine, cpu, memory (expected format for machine-compare init) + if (machineData) { + return { + machine: machineName, + cpu: machineData.allocatable?.cpu, + memory: machineData.allocatable?.memory, + } + } + // Return empty object if no machine found + return { + machine: machineName || '', + cpu: '', + memory: '', + } + } + + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` + + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' + + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + + // Return array with text and value object (expected format for machine-compare loader) + const machines = nodeGroups?.map((item) => { + const text = item.topologyValue + const subtext = `CPU: ${item.allocatable?.cpu}, Memory: ${item.allocatable?.memory}` + return { + text, + subtext, + value: { + machine: item.topologyValue, + cpu: item.allocatable?.cpu, + memory: item.allocatable?.memory, + }, + } + }) + + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) + + return dependantIndex === -1 ? machines : filteredMachine + } + + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, '/allowedMachine-min') + const maxMachineObj = getValue(discriminator, '/allowedMachine-max') + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + annotations['kubernetes.io/instance-type'] = minMaxMachine + + // Use cpu/memory directly from the machine objects + const minMachineAllocatable = minMachineObj + ? { cpu: minMachineObj.cpu, memory: minMachineObj.memory } + : null + const maxMachineAllocatable = maxMachineObj + ? { cpu: maxMachineObj.cpu, memory: maxMachineObj.memory } + : null + const allowedPath = `/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== minMaxMachine) { + commit('wizard/model$update', { + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: { ...annotations }, + force: true, + }) + } + } + + function hasNoAnnotations() { + return !hasAnnotations() + } + + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, + }) + return list + } + + async function fetchNodeTopology() { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const url = `/clusters/${owner}/${cluster}/proxy/node.k8s.appscode.com/v1alpha1/nodetopologies` + try { + const resp = await axios.get(url) + const list = (resp && resp.data?.items) || [] + const mappedList = list.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return name + }) + return mappedList + } catch (e) { + console.log(e) + } + return [] + } + + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } + + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) + } + + function setApplyToIfReady() { + return 'IfReady' + } + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources + } catch (e) { + console.log(e) + return [] + } + } + + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) + + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans + } + + /********** Monitoring **********/ + + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } + + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMySQL/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/monitor') + } + + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', + force: true, + }) + } + + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } + + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter') + } + } + + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } + + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } + + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComMySQL/spec/metadata/labels') + + const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') + + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } + + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) + + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } + + function getOpsRequestUrl(reqType) { + const cluster = storeGet('/route/params/cluster') + const domain = storeGet('/domain') || '' + const owner = storeGet('/route/params/user') + const dbname = getValue(model, '/metadata/release/name') + const group = getValue(model, '/metadata/resource/group') + const kind = getValue(model, '/metadata/resource/kind') + const namespace = getValue(model, '/metadata/release/namespace') + const resource = getValue(model, '/metadata/resource/name') + const version = getValue(model, '/metadata/resource/version') + const routeRootPath = storeGet('/route/path') + const pathPrefix = `${domain}/db${routeRootPath}` + const pathSplit = pathPrefix.split('/').slice(0, -1).join('/') + const pathConstructedForKubedb = pathSplit + `/${reqType.toLowerCase()}?namespace=${namespace}` + + const isKube = !!storeGet('/route/params/actions') + + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mysqlopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name', + ) + } + } + + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } + + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) + } + + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } + + function onValueFromChange() { + const valueFrom = getValue(discriminator, '/valueFromType') + if (valueFrom === 'input') { + if (isConfigMapTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/configMapKeyRef', + value: true, + }) + if (isSecretTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/secretKeyRef', + value: true, + }) + } else if (valueFrom === 'secret') { + if (!isSecretTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/secretKeyRef', + value: false, + }) + if (isConfigMapTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/configMapKeyRef', + value: true, + }) + } else if (valueFrom === 'configMap') { + if (!isConfigMapTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/configMapKeyRef', + value: false, + }) + if (isSecretTypeValueFrom()) + commit('wizard/model$update', { + path: 'temp/valueFrom/secretKeyRef', + value: true, + }) + } + } + + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } + + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') + + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) + + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } + + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } + + async function getConfigMapKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + // const namespace = getValue(reusableElementCtx, '/dataContext/namespace') // not supported + const namespace = getValue(model, '/metadata/release/namespace') + const configMapName = getValue( + model, + `/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') + + if (!configMapName) return [] + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) + + const configMaps = (resp && resp.data && resp.data.data) || {} + + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) + + return configMapKeys + } catch (e) { + console.log(e) + return [] + } + } + + async function getSecrets() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) + + const secrets = (resp && resp.data && resp.data.items) || [] + + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } catch (e) { + console.log(e) + return [] + } + } + + async function getSecretKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + // const namespace = getValue(reusableElementCtx, '/dataContext/namespace') // not supported + const namespace = getValue(model, '/metadata/release/namespace') + const secretName = getValue( + model, + `/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') + + if (!secretName) return [] + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) + + const secret = (resp && resp.data && resp.data.data) || {} + + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) + + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } + + function returnFalse() { + return false + } + + /********** Binding **********/ + + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMySQLBinding') + return isExposeBinding + } + + function addOrRemoveBinding() { + const value = getValue(discriminator, `/binding`) + const dbName = getValue(model, '/metadata/release/name') + const dbNamespace = getValue(model, '/metadata/release/namespace') + const labels = getValue(model, '/resources/kubedbComMySQL/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'MySQLBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } + + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComMySQLBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMySQLBinding') + } + } + + function handleUnit(path, type = 'bound') { + let value = getValue(model, `/resources/${path}`) + if (type === 'scalingRules') { + const updatedValue = [] + value?.forEach((ele) => { + let appliesUpto = ele['appliesUpto'] + let threshold = ele['threshold'] + if (appliesUpto && !isNaN(appliesUpto)) { + appliesUpto += 'Gi' + } + if (!isNaN(threshold)) { + threshold += 'pc' + } + updatedValue.push({ threshold, appliesUpto }) + }) + if (JSON.stringify(updatedValue) !== JSON.stringify(value)) { + commit('wizard/model$update', { + path: `/resources/${path}`, + value: updatedValue, + force: true, + }) + } + } else { + if (!isNaN(value)) { + value += 'Gi' + commit('wizard/model$update', { + path: `/resources/${path}`, + value: value, + force: true, + }) + } + } + } + + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } + function showStorageMemoryOption() { + return showStoragememory + } + + function onEnvArrayChange() { + const env = getValue(discriminator, '/env') || [] + let ret = {} + // filter out temp values + const filteredEnv = env?.map((item) => { + const { temp, ...rest } = item + if (temp?.valueFromType === 'input') { + const { name, value } = rest + ret = { name, value } + } else if (temp?.valueFromType === 'configMap') { + const { name } = rest + const { configMapKeyRef } = rest?.valueFrom || {} + ret = { name, valueFrom: { configMapKeyRef } } + } else if (temp?.valueFromType === 'secret') { + const { name } = rest + const { secretKeyRef } = rest?.valueFrom || {} + ret = { name, valueFrom: { secretKeyRef } } + } + return ret + }) + + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } + + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env') + + return env || [] + } + + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } + + function initMonitoring() { + const env = + getValue(model, '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env') || [] + setDiscriminatorValue('/env', env) + let tempEnv = [] + env.forEach((item) => { + let radio = '' + if (item.value) radio = 'input' + else if (item.valueFrom && item.valueFrom.configMapKeyRef) radio = 'configMap' + else if (item.valueFrom && item.valueFrom.secretKeyRef) radio = 'secret' + tempEnv.push({ ...item, temp: { valueFromType: radio } }) + }) + setDiscriminatorValue('/env', tempEnv) + } + + return { + initScheduleBackup, + initScheduleBackupForEdit, + onScheduleBackupChange, + showBackupForm, + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + onBackupTypeChange, + isBackupType, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + showConfigList, + showSchedule, + showScheduleBackup, + getDefaultSchedule, + onInputChangeSchedule, + setPausedValue, + + isKubedb, + isConsole, + getNamespaces, + isRancherManaged, + getMysqlDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onNamespaceChange, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + isBindingAlreadyOn, + addOrRemoveBinding, + + setValueFromDbDetails, + showStorageMemoryOption, + } +}